UNPKG

3.83 kBJavaScriptView Raw
1const path = require('path');
2const webpack = require('webpack');
3const { existsSync } = require('fs');
4const CaseSensitivePathsPlugin = require('case-sensitive-paths-webpack-plugin');
5const DuplicatePackageCheckerPlugin = require('duplicate-package-checker-webpack-plugin');
6const { BundleAnalyzerPlugin } = require('webpack-bundle-analyzer');
7const loaders = require('./loaders');
8const resolveModule = require('./helpers/resolve-module');
9const babelPreset = require('./babel-preset');
10
11process.noDeprecation = true;
12
13const 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 // Tell webpack what directories should be searched when resolving modules
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 // This set of options is identical to the resolve property set above,
78 // but is used only to resolve webpack's loader packages.
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 // Ignore all the moment local files
137 new webpack.IgnorePlugin(/^\.\/locale$/, /moment$/),
138
139 new CaseSensitivePathsPlugin()
140 ]
141 };
142
143 return config;
144};
145
146module.exports = plugin;