1 | const path = require('path');
|
2 | const webpack = require('webpack');
|
3 | const { existsSync } = require('fs');
|
4 | const CaseSensitivePathsPlugin = require('case-sensitive-paths-webpack-plugin');
|
5 | const DuplicatePackageCheckerPlugin = require('duplicate-package-checker-webpack-plugin');
|
6 | const { BundleAnalyzerPlugin } = require('webpack-bundle-analyzer');
|
7 | const loaders = require('./loaders');
|
8 | const resolveModule = require('./helpers/resolve-module');
|
9 | const babelPreset = require('./babel-preset');
|
10 |
|
11 | process.noDeprecation = true;
|
12 |
|
13 | const plugin = settings => {
|
14 | const babelrcPath = path.join(settings.project(), '.babelrc');
|
15 | const babelrcExists = existsSync(babelrcPath);
|
16 | const resolveApp = relativePath => path.resolve(settings.app(), relativePath);
|
17 |
|
18 | function getVersion() {
|
19 | return settings.pkg().version || 'N/A';
|
20 | }
|
21 |
|
22 | const config = {
|
23 | context: settings.app(),
|
24 |
|
25 | optimization: {
|
26 | splitChunks: {
|
27 | cacheGroups: {
|
28 | styles: {
|
29 | name: 'styles',
|
30 | test: /\.css$/,
|
31 | chunks: 'all',
|
32 | enforce: true
|
33 | },
|
34 | commons: {
|
35 | chunks: 'initial',
|
36 | minChunks: 2
|
37 | },
|
38 | vendor: {
|
39 | test: /node_modules/,
|
40 | chunks: 'initial',
|
41 | name: 'vendor',
|
42 | priority: 10,
|
43 | enforce: true
|
44 | }
|
45 | }
|
46 | },
|
47 | minimizer: []
|
48 | },
|
49 |
|
50 | entry: {
|
51 | index: [
|
52 | require.resolve('react-app-polyfill/ie11'),
|
53 | require.resolve('navigator.sendbeacon'),
|
54 | resolveModule(resolveApp, 'index')
|
55 | ]
|
56 | },
|
57 |
|
58 | output: {
|
59 | path: settings.output(),
|
60 | filename: settings.fileName()
|
61 | },
|
62 |
|
63 | devtool: 'cheap-module-source-map',
|
64 |
|
65 | resolve: {
|
66 |
|
67 | modules: [
|
68 | settings.app(),
|
69 | 'node_modules',
|
70 | path.join(settings.project(), 'node_modules'),
|
71 | path.join(__dirname, 'node_modules')
|
72 | ],
|
73 | symlinks: true,
|
74 | extensions: ['.js', '.jsx', '.ts', '.tsx', '.json', '.css', 'scss']
|
75 | },
|
76 |
|
77 |
|
78 |
|
79 | resolveLoader: {
|
80 | modules: [path.join(settings.project(), 'node_modules'), path.join(__dirname, 'node_modules')],
|
81 | symlinks: true
|
82 | },
|
83 |
|
84 | module: {
|
85 | rules: [
|
86 | {
|
87 | test: /\.(js|mjs|jsx|ts|tsx)$/,
|
88 | include: settings.include(),
|
89 | use: [
|
90 | {
|
91 | loader: 'babel-loader',
|
92 | options: {
|
93 | presets: [babelPreset],
|
94 | cacheDirectory: settings.isDevelopment(),
|
95 | babelrc: babelrcExists
|
96 | }
|
97 | }
|
98 | ]
|
99 | },
|
100 |
|
101 | loaders.css.production,
|
102 | loaders.scss.production,
|
103 | loaders.fonts,
|
104 | loaders.images
|
105 | ]
|
106 | },
|
107 | plugins: [
|
108 | new webpack.DefinePlugin(settings.globals('')),
|
109 |
|
110 | new webpack.BannerPlugin({
|
111 | banner: `APP_VERSION=${JSON.stringify(getVersion())};`,
|
112 | test: /\.(js|mjs|jsx|ts|tsx)$/,
|
113 | raw: true,
|
114 | entryOnly: true
|
115 | }),
|
116 |
|
117 | new webpack.BannerPlugin({
|
118 | banner: `v${getVersion()} - ${new Date().toJSON()}`
|
119 | }),
|
120 |
|
121 | new BundleAnalyzerPlugin({
|
122 | analyzerMode: 'static',
|
123 | reportFilename: 'profile.html'
|
124 | }),
|
125 |
|
126 | new loaders.MiniCssExtractPlugin({
|
127 | filename: 'css/[name]-[contenthash].css'
|
128 | }),
|
129 |
|
130 | new DuplicatePackageCheckerPlugin({
|
131 | exclude(instance) {
|
132 | return instance.name === 'regenerator-runtime';
|
133 | }
|
134 | }),
|
135 |
|
136 |
|
137 | new webpack.IgnorePlugin(/^\.\/locale$/, /moment$/),
|
138 |
|
139 | new CaseSensitivePathsPlugin()
|
140 | ]
|
141 | };
|
142 |
|
143 | return config;
|
144 | };
|
145 |
|
146 | module.exports = plugin;
|