@seamlessdocs/payment-modals 1.0.65 → 2.0.0-beta.10

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.
@@ -11,7 +11,7 @@ const CaseSensitivePathsPlugin = require('case-sensitive-paths-webpack-plugin');
11
11
  const InlineChunkHtmlPlugin = require('react-dev-utils/InlineChunkHtmlPlugin');
12
12
  const TerserPlugin = require('terser-webpack-plugin');
13
13
  const MiniCssExtractPlugin = require('mini-css-extract-plugin');
14
- const OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin');
14
+ const CssMinimizerPlugin = require('css-minimizer-webpack-plugin');
15
15
  const safePostCssParser = require('postcss-safe-parser');
16
16
  const ManifestPlugin = require('webpack-manifest-plugin');
17
17
  const InterpolateHtmlPlugin = require('react-dev-utils/InterpolateHtmlPlugin');
@@ -242,19 +242,9 @@ module.exports = function(webpackEnv) {
242
242
  sourceMap: shouldUseSourceMap,
243
243
  }),
244
244
  // This is only used in production mode
245
- new OptimizeCSSAssetsPlugin({
246
- cssProcessorOptions: {
247
- parser: safePostCssParser,
248
- map: shouldUseSourceMap
249
- ? {
250
- // `inline: false` forces the sourcemap to be output into a
251
- // separate file
252
- inline: false,
253
- // `annotation: true` appends the sourceMappingURL to the end of
254
- // the css file, helping the browser find the sourcemap
255
- annotation: true,
256
- }
257
- : false,
245
+ new CssMinimizerPlugin({
246
+ minimizerOptions: {
247
+ preset: ['default'],
258
248
  },
259
249
  }),
260
250
  ],
@@ -305,6 +295,18 @@ module.exports = function(webpackEnv) {
305
295
  // Make sure your source files are compiled, as they will not be processed in any way.
306
296
  new ModuleScopePlugin(paths.appSrc, [paths.appPackageJson]),
307
297
  ],
298
+ // Some libraries import Node modules but don't use them in the browser.
299
+ // Tell Webpack to provide empty mocks for them so importing them works.
300
+ fallback: {
301
+ module: false,
302
+ dgram: false,
303
+ dns: false,
304
+ fs: false,
305
+ http2: false,
306
+ net: false,
307
+ tls: false,
308
+ child_process: false,
309
+ },
308
310
  },
309
311
  resolveLoader: {
310
312
  plugins: [
@@ -637,18 +639,6 @@ module.exports = function(webpackEnv) {
637
639
  formatter: isEnvProduction ? typescriptFormatter : undefined,
638
640
  }),
639
641
  ].filter(Boolean),
640
- // Some libraries import Node modules but don't use them in the browser.
641
- // Tell Webpack to provide empty mocks for them so importing them works.
642
- node: {
643
- module: 'empty',
644
- dgram: 'empty',
645
- dns: 'mock',
646
- fs: 'empty',
647
- http2: 'empty',
648
- net: 'empty',
649
- tls: 'empty',
650
- child_process: 'empty',
651
- },
652
642
  // Turn off performance processing because we utilize
653
643
  // our own hints via the FileSizeReporter
654
644
  performance: false,
@@ -28,16 +28,25 @@ module.exports = function(proxy, allowedHost) {
28
28
  // So we will disable the host check normally, but enable it if you have
29
29
  // specified the `proxy` setting. Finally, we let you override it if you
30
30
  // really know what you're doing with a special environment variable.
31
- disableHostCheck:
32
- !proxy || process.env.DANGEROUSLY_DISABLE_HOST_CHECK === 'true',
31
+ // WebpackDevServer 2.4.3 introduced a security fix that prevents remote
32
+ // websites from potentially accessing local content through DNS rebinding.
33
+ // For Webpack 5, we use allowedHosts instead of disableHostCheck
34
+ allowedHosts: proxy || process.env.DANGEROUSLY_DISABLE_HOST_CHECK === 'true'
35
+ ? 'all'
36
+ : 'auto',
33
37
  // Enable gzip compression of generated files.
34
38
  compress: true,
35
39
  // Silence WebpackDevServer's own logs since they're generally not useful.
36
40
  // It will still show compile warnings and errors with this setting.
37
- clientLogLevel: 'none',
41
+ client: {
42
+ logging: 'none',
43
+ webSocketURL: allowedHost ? {
44
+ hostname: allowedHost,
45
+ } : undefined,
46
+ },
38
47
  // By default WebpackDevServer serves physical files from current directory
39
48
  // in addition to all the virtual build products that it serves from memory.
40
- // This is confusing because those files wont automatically be available in
49
+ // This is confusing because those files won't automatically be available in
41
50
  // production build folder unless we copy them. However, copying the whole
42
51
  // project directory is dangerous because we may expose sensitive files.
43
52
  // Instead, we establish a convention that only files in `public` directory
@@ -49,21 +58,23 @@ module.exports = function(proxy, allowedHost) {
49
58
  // for files like `favicon.ico`, `manifest.json`, and libraries that are
50
59
  // for some reason broken when imported through Webpack. If you just want to
51
60
  // use an image, put it in `src` and `import` it from JavaScript instead.
52
- contentBase: paths.appPublic,
53
- // By default files from `contentBase` will not trigger a page reload.
54
- watchContentBase: true,
61
+ static: {
62
+ directory: paths.appPublic,
63
+ watch: true,
64
+ },
55
65
  // Enable hot reloading server. It will provide /sockjs-node/ endpoint
56
66
  // for the WebpackDevServer client so it can learn when the files were
57
67
  // updated. The WebpackDevServer client is included as an entry point
58
68
  // in the Webpack development configuration. Note that only changes
59
69
  // to CSS are currently hot reloaded. JS changes will refresh the browser.
60
70
  hot: true,
71
+ liveReload: false,
61
72
  // It is important to tell WebpackDevServer to use the same "root" path
62
73
  // as we specified in the config. In development, we always serve from /.
63
74
  publicPath: '/',
64
75
  // WebpackDevServer is noisy by default so we emit custom message instead
65
76
  // by listening to the compiler events with `compiler.hooks[...].tap` calls above.
66
- quiet: true,
77
+ // Note: 'quiet' option is deprecated in Webpack 5, use client.logging instead
67
78
  // Reportedly, this avoids CPU overload on some systems.
68
79
  // https://github.com/facebook/create-react-app/issues/293
69
80
  // src/node_modules is not ignored to support absolute imports
@@ -80,16 +91,19 @@ module.exports = function(proxy, allowedHost) {
80
91
  // See https://github.com/facebook/create-react-app/issues/387.
81
92
  disableDotRule: true,
82
93
  },
83
- public: allowedHost,
84
94
  proxy,
85
- before(app, server) {
95
+ setupMiddlewares: (middlewares, devServer) => {
96
+ if (!devServer) {
97
+ throw new Error('webpack-dev-server is not defined');
98
+ }
99
+ const app = devServer.app;
86
100
  if (fs.existsSync(paths.proxySetup)) {
87
101
  // This registers user provided middleware for proxy reasons
88
102
  require(paths.proxySetup)(app);
89
103
  }
90
104
 
91
105
  // This lets us fetch source contents from webpack for the error overlay
92
- app.use(evalSourceMapMiddleware(server));
106
+ app.use(evalSourceMapMiddleware(devServer));
93
107
  // This lets us open files from the runtime error overlay.
94
108
  app.use(errorOverlayMiddleware());
95
109
 
@@ -99,6 +113,7 @@ module.exports = function(proxy, allowedHost) {
99
113
  // it used the same host and port.
100
114
  // https://github.com/facebook/create-react-app/issues/2272#issuecomment-302832432
101
115
  app.use(noopServiceWorkerMiddleware());
116
+ return middlewares;
102
117
  },
103
118
  };
104
119
  };
package/index.html CHANGED
@@ -3,7 +3,7 @@
3
3
  <head>
4
4
  <meta charset="utf-8" />
5
5
  <meta name="viewport" content="width=device-width, initial-scale=1" />
6
- <link rel="stylesheet" href="index.css" />
6
+ <!--<link rel="stylesheet" href="index.css" /> -->
7
7
  <title>Payment Modals</title>
8
8
  </head>
9
9
  <body>
@@ -22,7 +22,6 @@
22
22
  </div>
23
23
  <div id="payment-modal"></div>
24
24
  <script src="https://core.spreedly.com/iframe/express-2.min.js"></script>
25
- <script src="./build/payment-modals.js"></script>
26
25
  <script>
27
26
  var triggers = document.querySelectorAll('.links a');
28
27
  var callbacks = {
package/package.json CHANGED
@@ -1,62 +1,68 @@
1
1
  {
2
2
  "name": "@seamlessdocs/payment-modals",
3
- "version": "1.0.65",
3
+ "version": "2.0.0-beta.10",
4
4
  "description": "Payment modals for SeamlessDocs",
5
5
  "main": "build/payment-modals.js",
6
6
  "repository": {
7
7
  "url": "https://github.com/SeamlessDocsDev/PaymentModals"
8
8
  },
9
+ "engines": {
10
+ "node": ">=22.0.0"
11
+ },
9
12
  "scripts": {
10
13
  "start": "webpack-dev-server --mode development",
11
- "dev": "webpack --mode development ./src/index.jsx --output ./build/payment-modals.js",
12
- "build": "webpack --mode production ./src/index.jsx --output ./build/payment-modals.js"
14
+ "dev": "webpack --mode development",
15
+ "build": "webpack --mode production"
13
16
  },
14
17
  "devDependencies": {
15
- "@babel/core": "^7.6.2",
16
- "@babel/plugin-syntax-class-properties": "^7.2.0",
17
- "@babel/plugin-transform-runtime": "^7.4.4",
18
- "@babel/preset-env": "^7.6.2",
19
- "@babel/preset-react": "^7.0.0",
20
- "@babel/runtime": "^7.4.5",
21
- "babel-eslint": "^10.0.1",
22
- "babel-loader": "^8.0.6",
23
- "babel-plugin-transform-class-properties": "^6.24.1",
24
- "css-loader": "^2.1.1",
25
- "eslint": "^5.16.0",
26
- "eslint-config-airbnb": "^17.1.0",
27
- "eslint-config-prettier": "^4.2.0",
28
- "eslint-plugin-import": "^2.14.0",
29
- "eslint-plugin-jsx-a11y": "^6.1.1",
30
- "eslint-plugin-prettier": "^3.0.1",
31
- "eslint-plugin-react": "^7.13.0",
32
- "extract-text-webpack-plugin": "^3.0.2",
33
- "file-loader": "^3.0.1",
18
+ "@babel/core": "^7.23.7",
19
+ "@babel/eslint-parser": "^7.23.3",
20
+ "@babel/plugin-syntax-class-properties": "^7.12.13",
21
+ "@babel/plugin-transform-runtime": "^7.23.7",
22
+ "@babel/preset-env": "^7.23.7",
23
+ "@babel/preset-react": "^7.23.3",
24
+ "@babel/runtime": "^7.23.7",
25
+ "babel-loader": "^9.1.3",
26
+ "css-loader": "^6.8.1",
27
+ "css-minimizer-webpack-plugin": "^5.0.1",
28
+ "eslint": "^8.56.0",
29
+ "eslint-config-airbnb": "^19.0.4",
30
+ "eslint-config-prettier": "^9.1.0",
31
+ "eslint-plugin-import": "^2.29.1",
32
+ "eslint-plugin-jsx-a11y": "^6.8.0",
33
+ "eslint-plugin-prettier": "^5.2.0",
34
+ "eslint-plugin-react": "^7.33.2",
35
+ "eslint-plugin-react-hooks": "^4.6.0",
36
+ "file-loader": "^6.2.0",
37
+ "html-loader": "^4.2.0",
38
+ "html-webpack-plugin": "^5.6.0",
34
39
  "image-webpack-loader": "^6.0.0",
35
- "mini-css-extract-plugin": "^0.5.0",
36
- "node-sass": "^4.11.0",
37
- "prettier": "^1.17.0",
38
- "sass-loader": "^7.1.0",
39
- "style-loader": "^0.23.1",
40
+ "mini-css-extract-plugin": "^2.7.6",
41
+ "postcss": "^8.4.35",
42
+ "prettier": "^3.2.5",
43
+ "sass": "^1.69.0",
44
+ "sass-loader": "^13.3.0",
45
+ "style-loader": "^3.3.3",
40
46
  "svg-inline-loader": "^0.8.0",
41
- "url-loader": "^1.1.2",
42
- "webpack": "^4.41.0",
43
- "webpack-cli": "^3.3.9",
44
- "webpack-dev-server": "^3.2.1"
47
+ "url-loader": "^4.1.1",
48
+ "webpack": "^5.89.0",
49
+ "webpack-cli": "^5.1.4",
50
+ "webpack-dev-server": "^5.0.0"
45
51
  },
46
52
  "dependencies": {
47
- "@kofile/platform-react-payrix": "1.6.15",
53
+ "@kofile/platform-react-payrix": "1.7.47",
54
+ "@tippyjs/react": "^4.2.6",
48
55
  "babel-plugin-import": "^1.11.0",
49
56
  "base64-image-loader": "^1.2.1",
50
57
  "classnames": "^2.2.6",
51
58
  "download": "^7.1.0",
52
59
  "formik": "^2.1.5",
53
- "postcss-loader": "^3.0.0",
60
+ "postcss-loader": "^7.3.4",
54
61
  "postcss-nested": "^4.1.2",
55
62
  "prop-types": "^15.7.2",
56
- "react": "^16.10.1",
57
- "react-dom": "^16.10.1",
58
- "react-inlinesvg": "^1.1.7",
59
- "react-select": "^3.1.0",
60
- "react-tippy": "^1.4.0"
63
+ "react": "^18.2.0",
64
+ "react-dom": "^18.2.0",
65
+ "react-inlinesvg": "^4.2.0",
66
+ "react-select": "^5.8.0"
61
67
  }
62
68
  }
@@ -1,7 +1,7 @@
1
1
  import React from 'react';
2
2
  import classNames from 'classnames';
3
3
  import PropTypes from 'prop-types';
4
- import { Tooltip } from 'react-tippy';
4
+ import Tippy from '@tippyjs/react';
5
5
 
6
6
  import { Field } from 'formik';
7
7
 
@@ -10,7 +10,7 @@ import validIcon from '../../../../assets/img/valid-icon.svg';
10
10
 
11
11
  import styles from './FieldContainer.module.css';
12
12
 
13
- import 'react-tippy/dist/tippy.css';
13
+ import 'tippy.js/dist/tippy.css';
14
14
 
15
15
  const FieldContainer = ({ name, label, children }) => {
16
16
  return (
@@ -24,9 +24,9 @@ const FieldContainer = ({ name, label, children }) => {
24
24
  <div className={styles.fieldHeader}>
25
25
  <div className={styles.fieldName}>{label}</div>
26
26
  {meta.touched && meta.error && (
27
- <Tooltip title={meta.error} arrow>
27
+ <Tippy content={meta.error} arrow>
28
28
  <img src={errorIcon} alt="error" />
29
- </Tooltip>
29
+ </Tippy>
30
30
  )}
31
31
  {meta.touched && !meta.error && (
32
32
  <img className={styles.validationIcon} src={validIcon} alt="valid" />
package/src/index.jsx CHANGED
@@ -1,6 +1,5 @@
1
1
  import React from 'react';
2
- import ReactDOM from 'react-dom';
3
-
2
+ import ReactDOM from 'react-dom/client';
4
3
  import ChooseModal from './Components/ChooseModal';
5
4
  import ProcessingModal from './Components/ProcessingModal';
6
5
  import ErrorModal from './Components/ErrorModal';
@@ -14,12 +13,47 @@ import GovOSPayInvoiceSummaryModal from './Components/GovOSPayInvoiceSummaryModa
14
13
 
15
14
  import { restoreNativeEventConstructor, loadJQuery } from './shims';
16
15
 
16
+ import '../index.css';
17
17
  import './OpenViewStyles.css';
18
18
 
19
+ // Store root instances to manage React 18 roots
20
+ const rootInstances = new Map();
21
+
22
+ // Helper function to get createRoot
23
+ // React and ReactDOM are bundled internally, so we use the imported version directly
24
+ const getCreateRoot = () => {
25
+ if (ReactDOM && typeof ReactDOM.createRoot === 'function') {
26
+ return ReactDOM.createRoot;
27
+ }
28
+
29
+ throw new Error(
30
+ 'createRoot is not available. ReactDOM.createRoot should be available from the bundled react-dom/client.'
31
+ );
32
+ };
33
+
34
+ // Helper function to render with React 18 createRoot
35
+ const renderModal = (element, containerId) => {
36
+ const containerElement = document.getElementById(containerId);
37
+ if (!containerElement) {
38
+ console.warn(`Container element with id "${containerId}" not found`);
39
+ return;
40
+ }
41
+
42
+ // Get or create root instance
43
+ let root = rootInstances.get(containerId);
44
+ if (!root) {
45
+ const createRoot = getCreateRoot();
46
+ root = createRoot(containerElement);
47
+ rootInstances.set(containerId, root);
48
+ }
49
+
50
+ root.render(element);
51
+ };
52
+
19
53
  const handlePaymentModal = {};
20
54
 
21
55
  handlePaymentModal.chooseModal = settings => {
22
- ReactDOM.render(
56
+ renderModal(
23
57
  <ChooseModal
24
58
  title={settings.title}
25
59
  description={settings.description}
@@ -28,16 +62,16 @@ handlePaymentModal.chooseModal = settings => {
28
62
  onWithPay={settings.callbacks.withPay}
29
63
  onClose={settings.callbacks.close}
30
64
  />,
31
- document.getElementById('payment-modal')
65
+ 'payment-modal'
32
66
  );
33
67
  };
34
68
 
35
69
  handlePaymentModal.processingModal = () => {
36
- ReactDOM.render(<ProcessingModal />, document.getElementById('payment-modal'));
70
+ renderModal(<ProcessingModal />, 'payment-modal');
37
71
  };
38
72
 
39
73
  handlePaymentModal.errorModal = settings => {
40
- ReactDOM.render(
74
+ renderModal(
41
75
  <ErrorModal
42
76
  isOptional={settings.isOptional}
43
77
  errorText={settings.errorText}
@@ -45,19 +79,19 @@ handlePaymentModal.errorModal = settings => {
45
79
  onRetry={settings.callbacks.retry}
46
80
  onClose={settings.callbacks.close}
47
81
  />,
48
- document.getElementById('payment-modal')
82
+ 'payment-modal'
49
83
  );
50
84
  };
51
85
 
52
86
  handlePaymentModal.successModal = settings => {
53
- ReactDOM.render(
87
+ renderModal(
54
88
  <SuccessModal description={settings.description} />,
55
- document.getElementById('payment-modal')
89
+ 'payment-modal'
56
90
  );
57
91
  };
58
92
 
59
93
  handlePaymentModal.selectPaymentModal = settings => {
60
- ReactDOM.render(
94
+ renderModal(
61
95
  <SelectPaymentModal
62
96
  isPaymentRequired={settings.isPaymentRequired}
63
97
  onPayByBank={settings.callbacks.onPayByBank}
@@ -71,12 +105,12 @@ handlePaymentModal.selectPaymentModal = settings => {
71
105
  isCreditCardFeeEnable={settings.isCreditCardFeeEnable}
72
106
  isBankAccountFeeEnable={settings.isBankAccountFeeEnable}
73
107
  />,
74
- document.getElementById('payment-modal')
108
+ 'payment-modal'
75
109
  );
76
110
  };
77
111
 
78
112
  handlePaymentModal.achPaymentModal = settings => {
79
- ReactDOM.render(
113
+ renderModal(
80
114
  <ACHPaymentModal
81
115
  onPay={settings.callbacks.onPay}
82
116
  onClose={settings.callbacks.onClose}
@@ -86,14 +120,14 @@ handlePaymentModal.achPaymentModal = settings => {
86
120
  description={settings.description}
87
121
  feeName={settings.feeName}
88
122
  />,
89
- document.getElementById('payment-modal')
123
+ 'payment-modal'
90
124
  );
91
125
  };
92
126
 
93
127
  // TODO: Remove use of shims when mootools is removed
94
128
  handlePaymentModal.govOSPayACHPaymentModal = settings => {
95
129
  restoreNativeEventConstructor();
96
- ReactDOM.render(
130
+ renderModal(
97
131
  <GovOSPayACHPaymentModal
98
132
  onPay={settings.callbacks.onPay}
99
133
  onClose={settings.callbacks.onClose}
@@ -105,7 +139,7 @@ handlePaymentModal.govOSPayACHPaymentModal = settings => {
105
139
  updateTransactionUrl={settings.updateTransactionUrl}
106
140
  lineItems={settings.lineItems}
107
141
  />,
108
- document.getElementById('payment-modal')
142
+ 'payment-modal'
109
143
  );
110
144
  }
111
145
 
@@ -113,7 +147,7 @@ handlePaymentModal.govOSPayACHPaymentModal = settings => {
113
147
  handlePaymentModal.govOSPayCardPaymentModal = settings => {
114
148
  restoreNativeEventConstructor();
115
149
  loadJQuery(() => {
116
- ReactDOM.render(
150
+ renderModal(
117
151
  <GovOSPayCardPaymentModal
118
152
  onPay={settings.callbacks.onPay}
119
153
  onClose={settings.callbacks.onClose}
@@ -126,7 +160,7 @@ handlePaymentModal.govOSPayCardPaymentModal = settings => {
126
160
  updateTransactionUrl={settings.updateTransactionUrl}
127
161
  lineItems={settings.lineItems}
128
162
  />,
129
- document.getElementById('payment-modal')
163
+ 'payment-modal'
130
164
  );
131
165
  });
132
166
  }
@@ -134,18 +168,18 @@ handlePaymentModal.govOSPayCardPaymentModal = settings => {
134
168
  // TODO: Remove use of shims when mootools is removed
135
169
  handlePaymentModal.govOSPayInvoiceSummaryModal = settings => {
136
170
  restoreNativeEventConstructor();
137
- ReactDOM.render(
171
+ renderModal(
138
172
  <GovOSPayInvoiceSummaryModal
139
173
  onSubmit={settings.callbacks.onSubmit}
140
174
  onClose={settings.callbacks.onClose}
141
175
  transactionData={settings.transactionData}
142
176
  />,
143
- document.getElementById('payment-modal')
177
+ 'payment-modal'
144
178
  );
145
179
  }
146
180
 
147
181
  handlePaymentModal.none = () => {
148
- ReactDOM.render(<EmptyModal />, document.getElementById('payment-modal'));
182
+ renderModal(<EmptyModal />, 'payment-modal');
149
183
  };
150
184
 
151
185
  window.handlePaymentModal = handlePaymentModal;
package/webpack.config.js CHANGED
@@ -1,4 +1,6 @@
1
1
  const path = require('path');
2
+ const webpack = require('webpack');
3
+ const HtmlWebpackPlugin = require('html-webpack-plugin');
2
4
 
3
5
  module.exports = (_env, argv) => {
4
6
  const isProduction = argv.mode === 'production';
@@ -8,11 +10,18 @@ module.exports = (_env, argv) => {
8
10
  },
9
11
  output: {
10
12
  filename: 'payment-modals.js',
11
- path: '/build',
12
- library: 'payment-modals',
13
- libraryTarget: 'umd',
14
- umdNamedDefine: true
13
+ path: path.resolve(__dirname, 'build'),
14
+ library: {
15
+ name: 'payment-modals',
16
+ type: 'umd'
17
+ },
18
+ umdNamedDefine: true,
19
+ clean: true,
20
+ globalObject: 'this'
15
21
  },
22
+ // No externals - bundle everything including React and ReactDOM
23
+ // This makes the package fully self-contained
24
+ externals: {},
16
25
  module: {
17
26
  rules: [
18
27
  {
@@ -23,18 +32,20 @@ module.exports = (_env, argv) => {
23
32
  }
24
33
  },
25
34
  {
26
- test: /\.css$/,
35
+ test: /\.module\.css$/,
27
36
  use: [
28
37
  'style-loader',
29
38
  {
30
39
  loader: 'css-loader',
31
40
  options: {
32
41
  importLoaders: 1,
33
- modules: true
42
+ modules: {
43
+ localIdentName: '[local]__[hash:base64:5]',
44
+ exportLocalsConvention: 'camelCase'
45
+ }
34
46
  }
35
47
  }
36
- ],
37
- include: /\.module\.css$/
48
+ ]
38
49
  },
39
50
  {
40
51
  test: /\.css$/,
@@ -55,24 +66,41 @@ module.exports = (_env, argv) => {
55
66
  use: {
56
67
  loader: 'html-loader',
57
68
  options: {
58
- attrs: ['img:src', 'link:href']
69
+ sources: {
70
+ list: [
71
+ { tag: 'img', attribute: 'src', type: 'src' },
72
+ { tag: 'link', attribute: 'href', type: 'src' }
73
+ ]
74
+ }
59
75
  }
60
76
  }
61
77
  }
62
78
  ]
63
79
  },
80
+ plugins: [
81
+ new HtmlWebpackPlugin({
82
+ template: path.join(__dirname, 'index.html'),
83
+ inject: 'body',
84
+ scriptLoading: 'blocking'
85
+ })
86
+ ],
64
87
  devServer: {
65
88
  port: 9000,
66
89
  compress: true,
67
90
  open: true,
68
- publicPath: '/build/',
69
- contentBase: path.join(__dirname, 'build'),
91
+ static: [
92
+ {
93
+ directory: path.join(__dirname),
94
+ publicPath: '/',
95
+ watch: true
96
+ }
97
+ ],
70
98
  historyApiFallback: true
71
99
  },
72
100
  devtool: isProduction ? false : 'inline-source-map',
73
101
  resolve: {
74
- modules: [path.join(__dirname, 'src'), 'node_modules'],
75
- extensions: ['.js', '.jsx', '.scss'],
102
+ modules: [path.join(__dirname, 'src'), path.join(__dirname), 'node_modules'],
103
+ extensions: ['.js', '.jsx', '.scss', '.css'],
76
104
  alias: {
77
105
  'react-virtualized/List': 'react-virtualized/dist/es/List'
78
106
  }