react-image-gallery 1.2.12 → 1.4.0
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.
- package/LICENSE +1 -1
- package/README.md +170 -162
- package/build/image-gallery.es.js +1 -0
- package/build/image-gallery.js +1 -1
- package/build/image-gallery.umd.js +1 -0
- package/package.json +63 -41
- package/styles/css/image-gallery.css +1 -1
- package/styles/scss/image-gallery.scss +81 -20
- package/.babelrc +0 -1
- package/.eslintrc.json +0 -24
- package/.github/ISSUE_TEMPLATE/bug_report.md +0 -39
- package/.github/ISSUE_TEMPLATE/feature_request.md +0 -20
- package/.notes +0 -2
- package/src/ImageGallery.js +0 -1664
- package/src/Item.js +0 -79
- package/src/SVG.js +0 -65
- package/src/SwipeWrapper.js +0 -45
- package/src/controls/Fullscreen.js +0 -29
- package/src/controls/LeftNav.js +0 -30
- package/src/controls/PlayPause.js +0 -29
- package/src/controls/RightNav.js +0 -30
- package/tests/ImageGallery.test.js +0 -15
- package/tests/__snapshots__/ImageGallery.test.js.snap +0 -3
- package/tests/setupTestFramework.js +0 -4
- package/webpack.build.js +0 -172
- package/webpack.config.js +0 -49
package/src/Item.js
DELETED
|
@@ -1,79 +0,0 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
|
-
import { bool, func, string } from 'prop-types';
|
|
3
|
-
|
|
4
|
-
const defaultProps = {
|
|
5
|
-
description: '',
|
|
6
|
-
fullscreen: '',
|
|
7
|
-
isFullscreen: false,
|
|
8
|
-
originalAlt: '',
|
|
9
|
-
originalHeight: '',
|
|
10
|
-
originalWidth: '',
|
|
11
|
-
originalTitle: '',
|
|
12
|
-
sizes: '',
|
|
13
|
-
srcSet: '',
|
|
14
|
-
loading: 'eager',
|
|
15
|
-
};
|
|
16
|
-
|
|
17
|
-
const Item = React.memo((props) => {
|
|
18
|
-
const {
|
|
19
|
-
description,
|
|
20
|
-
fullscreen, // fullscreen version of img
|
|
21
|
-
handleImageLoaded,
|
|
22
|
-
isFullscreen,
|
|
23
|
-
onImageError,
|
|
24
|
-
original,
|
|
25
|
-
originalAlt,
|
|
26
|
-
originalHeight,
|
|
27
|
-
originalWidth,
|
|
28
|
-
originalTitle,
|
|
29
|
-
sizes,
|
|
30
|
-
srcSet,
|
|
31
|
-
loading,
|
|
32
|
-
} = {...defaultProps, ...props};
|
|
33
|
-
const itemSrc = isFullscreen ? (fullscreen || original) : original;
|
|
34
|
-
|
|
35
|
-
return (
|
|
36
|
-
<React.Fragment>
|
|
37
|
-
<img
|
|
38
|
-
className="image-gallery-image"
|
|
39
|
-
src={itemSrc}
|
|
40
|
-
alt={originalAlt}
|
|
41
|
-
srcSet={srcSet}
|
|
42
|
-
height={originalHeight}
|
|
43
|
-
width={originalWidth}
|
|
44
|
-
sizes={sizes}
|
|
45
|
-
title={originalTitle}
|
|
46
|
-
onLoad={event => handleImageLoaded(event, original)}
|
|
47
|
-
onError={onImageError}
|
|
48
|
-
loading={loading}
|
|
49
|
-
/>
|
|
50
|
-
{
|
|
51
|
-
description && (
|
|
52
|
-
<span className="image-gallery-description">
|
|
53
|
-
{description}
|
|
54
|
-
</span>
|
|
55
|
-
)
|
|
56
|
-
}
|
|
57
|
-
</React.Fragment>
|
|
58
|
-
);
|
|
59
|
-
});
|
|
60
|
-
|
|
61
|
-
Item.displayName = 'Item';
|
|
62
|
-
|
|
63
|
-
Item.propTypes = {
|
|
64
|
-
description: string,
|
|
65
|
-
fullscreen: string, // fullscreen version of img
|
|
66
|
-
handleImageLoaded: func.isRequired,
|
|
67
|
-
isFullscreen: bool,
|
|
68
|
-
onImageError: func.isRequired,
|
|
69
|
-
original: string.isRequired,
|
|
70
|
-
originalAlt: string,
|
|
71
|
-
originalHeight: string,
|
|
72
|
-
originalWidth: string,
|
|
73
|
-
originalTitle: string,
|
|
74
|
-
sizes: string,
|
|
75
|
-
srcSet: string,
|
|
76
|
-
loading: string,
|
|
77
|
-
};
|
|
78
|
-
|
|
79
|
-
export default Item;
|
package/src/SVG.js
DELETED
|
@@ -1,65 +0,0 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
|
-
import { number, oneOf, string } from 'prop-types';
|
|
3
|
-
|
|
4
|
-
const left = <polyline points="15 18 9 12 15 6" />;
|
|
5
|
-
const right = <polyline points="9 18 15 12 9 6" />;
|
|
6
|
-
const maximize = <path d="M8 3H5a2 2 0 0 0-2 2v3m18 0V5a2 2 0 0 0-2-2h-3m0 18h3a2 2 0 0 0 2-2v-3M3 16v3a2 2 0 0 0 2 2h3" />;
|
|
7
|
-
const minimize = <path d="M8 3v3a2 2 0 0 1-2 2H3m18 0h-3a2 2 0 0 1-2-2V3m0 18v-3a2 2 0 0 1 2-2h3M3 16h3a2 2 0 0 1 2 2v3" />;
|
|
8
|
-
const play = <polygon points="5 3 19 12 5 21 5 3" />;
|
|
9
|
-
const pause = (
|
|
10
|
-
<React.Fragment>
|
|
11
|
-
<rect x="6" y="4" width="4" height="16" />
|
|
12
|
-
<rect x="14" y="4" width="4" height="16" />
|
|
13
|
-
</React.Fragment>
|
|
14
|
-
);
|
|
15
|
-
|
|
16
|
-
const iconMapper = {
|
|
17
|
-
left,
|
|
18
|
-
right,
|
|
19
|
-
maximize,
|
|
20
|
-
minimize,
|
|
21
|
-
play,
|
|
22
|
-
pause,
|
|
23
|
-
};
|
|
24
|
-
|
|
25
|
-
const defaultProps = {
|
|
26
|
-
strokeWidth: 1,
|
|
27
|
-
viewBox: '0 0 24 24',
|
|
28
|
-
};
|
|
29
|
-
|
|
30
|
-
const SVG = (props) => {
|
|
31
|
-
const {
|
|
32
|
-
strokeWidth,
|
|
33
|
-
viewBox,
|
|
34
|
-
icon,
|
|
35
|
-
} = {...defaultProps, ...props};
|
|
36
|
-
return (
|
|
37
|
-
<svg
|
|
38
|
-
className="image-gallery-svg"
|
|
39
|
-
xmlns="http://www.w3.org/2000/svg"
|
|
40
|
-
viewBox={viewBox}
|
|
41
|
-
fill="none"
|
|
42
|
-
stroke="currentColor"
|
|
43
|
-
strokeWidth={strokeWidth}
|
|
44
|
-
strokeLinecap="round"
|
|
45
|
-
strokeLinejoin="round"
|
|
46
|
-
>
|
|
47
|
-
{iconMapper[icon]}
|
|
48
|
-
</svg>
|
|
49
|
-
);
|
|
50
|
-
};
|
|
51
|
-
|
|
52
|
-
SVG.propTypes = {
|
|
53
|
-
strokeWidth: number,
|
|
54
|
-
viewBox: string,
|
|
55
|
-
icon: oneOf([
|
|
56
|
-
'left',
|
|
57
|
-
'right',
|
|
58
|
-
'maximize',
|
|
59
|
-
'minimize',
|
|
60
|
-
'play',
|
|
61
|
-
'pause',
|
|
62
|
-
]).isRequired,
|
|
63
|
-
};
|
|
64
|
-
|
|
65
|
-
export default SVG;
|
package/src/SwipeWrapper.js
DELETED
|
@@ -1,45 +0,0 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
|
-
import {
|
|
3
|
-
string,
|
|
4
|
-
node,
|
|
5
|
-
number,
|
|
6
|
-
func,
|
|
7
|
-
} from 'prop-types';
|
|
8
|
-
import { useSwipeable } from 'react-swipeable';
|
|
9
|
-
|
|
10
|
-
const defaultProps = {
|
|
11
|
-
className: '',
|
|
12
|
-
delta: 0,
|
|
13
|
-
onSwiping: () => {},
|
|
14
|
-
onSwiped: () => {},
|
|
15
|
-
};
|
|
16
|
-
|
|
17
|
-
const SwipeWrapper = (props) => {
|
|
18
|
-
const {
|
|
19
|
-
children,
|
|
20
|
-
className,
|
|
21
|
-
delta,
|
|
22
|
-
onSwiping,
|
|
23
|
-
onSwiped,
|
|
24
|
-
} = {...defaultProps, ...props};
|
|
25
|
-
const swipeHandlers = useSwipeable({
|
|
26
|
-
delta,
|
|
27
|
-
onSwiping,
|
|
28
|
-
onSwiped,
|
|
29
|
-
});
|
|
30
|
-
return (
|
|
31
|
-
<div {...swipeHandlers} className={className}>
|
|
32
|
-
{children}
|
|
33
|
-
</div>
|
|
34
|
-
);
|
|
35
|
-
};
|
|
36
|
-
|
|
37
|
-
SwipeWrapper.propTypes = {
|
|
38
|
-
children: node.isRequired,
|
|
39
|
-
className: string,
|
|
40
|
-
delta: number,
|
|
41
|
-
onSwiped: func,
|
|
42
|
-
onSwiping: func,
|
|
43
|
-
};
|
|
44
|
-
|
|
45
|
-
export default SwipeWrapper;
|
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
|
-
import { bool, func } from 'prop-types';
|
|
3
|
-
import SVG from 'src/SVG';
|
|
4
|
-
|
|
5
|
-
const Fullscreen = React.memo(({
|
|
6
|
-
isFullscreen,
|
|
7
|
-
onClick,
|
|
8
|
-
}) => {
|
|
9
|
-
return (
|
|
10
|
-
<button
|
|
11
|
-
type="button"
|
|
12
|
-
className="image-gallery-icon image-gallery-fullscreen-button"
|
|
13
|
-
onClick={onClick}
|
|
14
|
-
aria-label="Open Fullscreen"
|
|
15
|
-
>
|
|
16
|
-
<SVG strokeWidth={2} icon={isFullscreen ? 'minimize' : 'maximize'} />
|
|
17
|
-
</button>
|
|
18
|
-
);
|
|
19
|
-
});
|
|
20
|
-
|
|
21
|
-
Fullscreen.displayName = 'Fullscreen';
|
|
22
|
-
|
|
23
|
-
Fullscreen.propTypes = {
|
|
24
|
-
isFullscreen: bool.isRequired,
|
|
25
|
-
onClick: func.isRequired,
|
|
26
|
-
};
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
export default Fullscreen;
|
package/src/controls/LeftNav.js
DELETED
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
|
-
import { bool, func } from 'prop-types';
|
|
3
|
-
import SVG from 'src/SVG';
|
|
4
|
-
|
|
5
|
-
const LeftNav = React.memo(({
|
|
6
|
-
disabled,
|
|
7
|
-
onClick,
|
|
8
|
-
}) => {
|
|
9
|
-
return (
|
|
10
|
-
<button
|
|
11
|
-
type="button"
|
|
12
|
-
className="image-gallery-icon image-gallery-left-nav"
|
|
13
|
-
disabled={disabled}
|
|
14
|
-
onClick={onClick}
|
|
15
|
-
aria-label="Previous Slide"
|
|
16
|
-
>
|
|
17
|
-
<SVG icon="left" viewBox="6 0 12 24" />
|
|
18
|
-
</button>
|
|
19
|
-
);
|
|
20
|
-
});
|
|
21
|
-
|
|
22
|
-
LeftNav.displayName = 'LeftNav';
|
|
23
|
-
|
|
24
|
-
LeftNav.propTypes = {
|
|
25
|
-
disabled: bool.isRequired,
|
|
26
|
-
onClick: func.isRequired,
|
|
27
|
-
};
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
export default LeftNav;
|
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
|
-
import { bool, func } from 'prop-types';
|
|
3
|
-
import SVG from 'src/SVG';
|
|
4
|
-
|
|
5
|
-
const PlayPause = React.memo(({
|
|
6
|
-
isPlaying,
|
|
7
|
-
onClick,
|
|
8
|
-
}) => {
|
|
9
|
-
return (
|
|
10
|
-
<button
|
|
11
|
-
type="button"
|
|
12
|
-
className="image-gallery-icon image-gallery-play-button"
|
|
13
|
-
onClick={onClick}
|
|
14
|
-
aria-label="Play or Pause Slideshow"
|
|
15
|
-
>
|
|
16
|
-
<SVG strokeWidth={2} icon={isPlaying ? 'pause' : 'play'} />
|
|
17
|
-
</button>
|
|
18
|
-
);
|
|
19
|
-
});
|
|
20
|
-
|
|
21
|
-
PlayPause.displayName = 'PlayPause';
|
|
22
|
-
|
|
23
|
-
PlayPause.propTypes = {
|
|
24
|
-
isPlaying: bool.isRequired,
|
|
25
|
-
onClick: func.isRequired,
|
|
26
|
-
};
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
export default PlayPause;
|
package/src/controls/RightNav.js
DELETED
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
|
-
import { bool, func } from 'prop-types';
|
|
3
|
-
import SVG from 'src/SVG';
|
|
4
|
-
|
|
5
|
-
const RightNav = React.memo(({
|
|
6
|
-
disabled,
|
|
7
|
-
onClick,
|
|
8
|
-
}) => {
|
|
9
|
-
return (
|
|
10
|
-
<button
|
|
11
|
-
type="button"
|
|
12
|
-
className="image-gallery-icon image-gallery-right-nav"
|
|
13
|
-
disabled={disabled}
|
|
14
|
-
onClick={onClick}
|
|
15
|
-
aria-label="Next Slide"
|
|
16
|
-
>
|
|
17
|
-
<SVG icon="right" viewBox="6 0 12 24" />
|
|
18
|
-
</button>
|
|
19
|
-
);
|
|
20
|
-
});
|
|
21
|
-
|
|
22
|
-
RightNav.displayName = 'RightNav';
|
|
23
|
-
|
|
24
|
-
RightNav.propTypes = {
|
|
25
|
-
disabled: bool.isRequired,
|
|
26
|
-
onClick: func.isRequired,
|
|
27
|
-
};
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
export default RightNav;
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
|
-
import { shallow } from 'enzyme';
|
|
3
|
-
|
|
4
|
-
import ImageGallery from '../src/ImageGallery';
|
|
5
|
-
|
|
6
|
-
describe('<ImageGallery />', () => {
|
|
7
|
-
const defaultProps = {
|
|
8
|
-
items: [],
|
|
9
|
-
};
|
|
10
|
-
|
|
11
|
-
it('matches snapshot', () => {
|
|
12
|
-
const component = shallow(<ImageGallery {...defaultProps} />);
|
|
13
|
-
expect(component).toMatchSnapshot();
|
|
14
|
-
});
|
|
15
|
-
});
|
package/webpack.build.js
DELETED
|
@@ -1,172 +0,0 @@
|
|
|
1
|
-
|
|
2
|
-
const path = require('path');
|
|
3
|
-
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
|
|
4
|
-
const RemovePlugin = require('remove-files-webpack-plugin');
|
|
5
|
-
|
|
6
|
-
const config = {
|
|
7
|
-
mode: 'production',
|
|
8
|
-
};
|
|
9
|
-
|
|
10
|
-
const jsOutput = Object.assign({}, config, {
|
|
11
|
-
entry: [ './src/ImageGallery.js', ],
|
|
12
|
-
output: {
|
|
13
|
-
path: path.resolve(__dirname, 'build'),
|
|
14
|
-
filename: 'image-gallery.js',
|
|
15
|
-
library: 'ImageGallery',
|
|
16
|
-
globalObject: 'this',
|
|
17
|
-
libraryTarget: 'umd',
|
|
18
|
-
},
|
|
19
|
-
resolve: {
|
|
20
|
-
alias: {
|
|
21
|
-
src: path.resolve(__dirname, 'src/'),
|
|
22
|
-
},
|
|
23
|
-
extensions: ['.js']
|
|
24
|
-
},
|
|
25
|
-
module: {
|
|
26
|
-
rules: [
|
|
27
|
-
{
|
|
28
|
-
test: /\.js$/,
|
|
29
|
-
exclude: /node_modules/,
|
|
30
|
-
loader: 'babel-loader',
|
|
31
|
-
}
|
|
32
|
-
]
|
|
33
|
-
},
|
|
34
|
-
externals: {
|
|
35
|
-
// Don't bundle react or react-dom
|
|
36
|
-
react: {
|
|
37
|
-
commonjs: 'react',
|
|
38
|
-
commonjs2: 'react',
|
|
39
|
-
amd: 'react',
|
|
40
|
-
root: 'React',
|
|
41
|
-
},
|
|
42
|
-
'react-dom': {
|
|
43
|
-
commonjs: 'react-dom',
|
|
44
|
-
commonjs2: 'react-dom',
|
|
45
|
-
amd: 'react-dom',
|
|
46
|
-
root: 'ReactDOM',
|
|
47
|
-
},
|
|
48
|
-
},
|
|
49
|
-
});
|
|
50
|
-
|
|
51
|
-
const cssOutput = Object.assign({}, config, {
|
|
52
|
-
entry: './styles/scss/image-gallery.scss',
|
|
53
|
-
output: {
|
|
54
|
-
path: path.resolve(__dirname, 'styles/css'),
|
|
55
|
-
},
|
|
56
|
-
module: {
|
|
57
|
-
rules: [
|
|
58
|
-
{
|
|
59
|
-
test: /\.(css|scss)$/i,
|
|
60
|
-
use: [
|
|
61
|
-
MiniCssExtractPlugin.loader,
|
|
62
|
-
// Translates CSS into CommonJS
|
|
63
|
-
'css-loader',
|
|
64
|
-
// Compiles Sass to CSS
|
|
65
|
-
'sass-loader',
|
|
66
|
-
],
|
|
67
|
-
}
|
|
68
|
-
]
|
|
69
|
-
},
|
|
70
|
-
plugins: [
|
|
71
|
-
new MiniCssExtractPlugin({
|
|
72
|
-
filename: 'image-gallery.css',
|
|
73
|
-
}),
|
|
74
|
-
new RemovePlugin({
|
|
75
|
-
/**
|
|
76
|
-
* After compilation permanently remove empty JS files created from CSS entries.
|
|
77
|
-
*/
|
|
78
|
-
after: {
|
|
79
|
-
test: [
|
|
80
|
-
{
|
|
81
|
-
folder: 'styles/css',
|
|
82
|
-
method: (absoluteItemPath) => {
|
|
83
|
-
return new RegExp(/\.js$/, 'm').test(absoluteItemPath);
|
|
84
|
-
},
|
|
85
|
-
}
|
|
86
|
-
]
|
|
87
|
-
}
|
|
88
|
-
}),
|
|
89
|
-
],
|
|
90
|
-
});
|
|
91
|
-
|
|
92
|
-
const jsDemoOutput = Object.assign({}, config, {
|
|
93
|
-
entry: [ './example/app.js', ],
|
|
94
|
-
output: {
|
|
95
|
-
path: path.resolve(__dirname, 'demo'),
|
|
96
|
-
filename: 'demo.mini.js',
|
|
97
|
-
},
|
|
98
|
-
resolve: {
|
|
99
|
-
alias: {
|
|
100
|
-
src: path.resolve(__dirname, 'src/'),
|
|
101
|
-
},
|
|
102
|
-
extensions: ['.js']
|
|
103
|
-
},
|
|
104
|
-
module: {
|
|
105
|
-
rules: [
|
|
106
|
-
{
|
|
107
|
-
test: /\.js$/,
|
|
108
|
-
loader: 'babel-loader',
|
|
109
|
-
}
|
|
110
|
-
]
|
|
111
|
-
},
|
|
112
|
-
plugins: [
|
|
113
|
-
new RemovePlugin({
|
|
114
|
-
/**
|
|
115
|
-
* After compilation permanently remove unused LICENSE.txt file
|
|
116
|
-
*/
|
|
117
|
-
after: {
|
|
118
|
-
test: [
|
|
119
|
-
{
|
|
120
|
-
folder: 'demo',
|
|
121
|
-
method: (absoluteItemPath) => {
|
|
122
|
-
return new RegExp(/\.txt$/).test(absoluteItemPath);
|
|
123
|
-
},
|
|
124
|
-
}
|
|
125
|
-
]
|
|
126
|
-
}
|
|
127
|
-
}),
|
|
128
|
-
],
|
|
129
|
-
});
|
|
130
|
-
|
|
131
|
-
const cssDemoOutput = Object.assign({}, config, {
|
|
132
|
-
entry: ['./styles/scss/image-gallery.scss', './example/app.css'],
|
|
133
|
-
output: {
|
|
134
|
-
path: path.resolve(__dirname, 'demo'),
|
|
135
|
-
},
|
|
136
|
-
module: {
|
|
137
|
-
rules: [
|
|
138
|
-
{
|
|
139
|
-
test: /\.(css|scss)$/i,
|
|
140
|
-
use: [
|
|
141
|
-
MiniCssExtractPlugin.loader,
|
|
142
|
-
// Translates CSS into CommonJS
|
|
143
|
-
'css-loader',
|
|
144
|
-
// Compiles Sass to CSS
|
|
145
|
-
'sass-loader',
|
|
146
|
-
],
|
|
147
|
-
}
|
|
148
|
-
]
|
|
149
|
-
},
|
|
150
|
-
plugins: [
|
|
151
|
-
new MiniCssExtractPlugin({
|
|
152
|
-
filename: 'demo.mini.css',
|
|
153
|
-
}),
|
|
154
|
-
new RemovePlugin({
|
|
155
|
-
/**
|
|
156
|
-
* After compilation permanently remove empty JS files created from CSS entries.
|
|
157
|
-
*/
|
|
158
|
-
after: {
|
|
159
|
-
test: [
|
|
160
|
-
{
|
|
161
|
-
folder: 'demo',
|
|
162
|
-
method: (absoluteItemPath) => {
|
|
163
|
-
return new RegExp(/\.js$/).test(absoluteItemPath);
|
|
164
|
-
},
|
|
165
|
-
}
|
|
166
|
-
]
|
|
167
|
-
}
|
|
168
|
-
}),
|
|
169
|
-
],
|
|
170
|
-
});
|
|
171
|
-
|
|
172
|
-
module.exports = [jsOutput, cssOutput, jsDemoOutput, cssDemoOutput];
|
package/webpack.config.js
DELETED
|
@@ -1,49 +0,0 @@
|
|
|
1
|
-
|
|
2
|
-
const path = require('path');
|
|
3
|
-
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
|
|
4
|
-
|
|
5
|
-
module.exports = {
|
|
6
|
-
entry: ['./example/app.js', './example/app.css', './styles/scss/image-gallery.scss'],
|
|
7
|
-
output: {
|
|
8
|
-
path: path.resolve(__dirname, 'example'),
|
|
9
|
-
filename: 'example.js',
|
|
10
|
-
publicPath: '/dist/'
|
|
11
|
-
},
|
|
12
|
-
resolve: {
|
|
13
|
-
extensions: ['.js'],
|
|
14
|
-
alias: {
|
|
15
|
-
src: path.resolve(__dirname, 'src/'),
|
|
16
|
-
},
|
|
17
|
-
},
|
|
18
|
-
module: {
|
|
19
|
-
rules: [
|
|
20
|
-
{
|
|
21
|
-
test: /\.(js|jsx)$/,
|
|
22
|
-
loader: 'babel-loader',
|
|
23
|
-
},
|
|
24
|
-
{
|
|
25
|
-
test: /\.(css|scss)$/i,
|
|
26
|
-
use: [
|
|
27
|
-
// Creates `style` nodes from JS strings
|
|
28
|
-
"style-loader",
|
|
29
|
-
// Translates CSS into CommonJS
|
|
30
|
-
"css-loader",
|
|
31
|
-
// Compiles Sass to CSS
|
|
32
|
-
"sass-loader",
|
|
33
|
-
],
|
|
34
|
-
}
|
|
35
|
-
]
|
|
36
|
-
},
|
|
37
|
-
plugins: [
|
|
38
|
-
new MiniCssExtractPlugin({
|
|
39
|
-
filename: 'image-gallery.css',
|
|
40
|
-
}),
|
|
41
|
-
],
|
|
42
|
-
devServer: {
|
|
43
|
-
host: '0.0.0.0',
|
|
44
|
-
port: 8001,
|
|
45
|
-
historyApiFallback: {
|
|
46
|
-
rewrites: [{ from: /\//, to: '/example/index.html' }],
|
|
47
|
-
},
|
|
48
|
-
},
|
|
49
|
-
};
|