UNPKG

4.68 kBJavaScriptView Raw
1const path = require('path');
2const webpack = require('webpack');
3const { existsSync } = require('fs');
4const HtmlWebpackPlugin = require('html-webpack-plugin');
5const WebpackNotifierPlugin = require('webpack-notifier');
6const CaseSensitivePathsPlugin = require('case-sensitive-paths-webpack-plugin');
7const ReactRefreshWebpackPlugin = require('@pmmmwh/react-refresh-webpack-plugin');
8const DuplicatePackageCheckerPlugin = require('duplicate-package-checker-webpack-plugin');
9const CopyWebpackPlugin = require('copy-webpack-plugin');
10const loaders = require('./loaders');
11const babelPreset = require('./babel-preset');
12const resolveModule = require('./helpers/resolve-module');
13const html = require('./html');
14
15process.noDeprecation = true;
16
17const plugin = settings => {
18 const resolveApp = relativePath => path.resolve(settings.app(), relativePath);
19
20 const babelrcPath = path.join(settings.project(), '.babelrc');
21 const babelrcExists = existsSync(babelrcPath);
22
23 function getVersion() {
24 return settings.pkg().version || 'N/A';
25 }
26
27 const index = [
28 require.resolve('react-app-polyfill/ie11'),
29 `${require.resolve('webpack-dev-server/client')}?/`,
30 require.resolve('webpack/hot/dev-server'),
31 require.resolve('navigator.sendbeacon'),
32 resolveModule(resolveApp, 'index')
33 ];
34
35 const config = {
36 mode: 'development',
37
38 context: settings.app(),
39
40 entry: {
41 index
42 },
43
44 output: {
45 path: settings.output(),
46 filename: settings.fileName(),
47 chunkFilename: settings.chunkFileName()
48 },
49
50 devtool: settings.sourceMap(),
51
52 resolve: {
53 // Tell webpack what directories should be searched when resolving modules
54 modules: [
55 settings.app(),
56 'node_modules',
57 path.join(settings.project(), 'node_modules'),
58 path.join(__dirname, 'node_modules')
59 ],
60 symlinks: true,
61 extensions: ['.js', '.jsx', '.ts', '.tsx', '.json', '.css', 'scss']
62 },
63
64 // This set of options is identical to the resolve property set above,
65 // but is used only to resolve webpack's loader packages.
66 resolveLoader: {
67 modules: [path.join(settings.project(), 'node_modules'), path.join(__dirname, 'node_modules')],
68 symlinks: true
69 },
70
71 module: {
72 rules: [
73 {
74 test: /\.(js|mjs|jsx|ts|tsx)$/,
75 include: settings.include(),
76 use: [
77 {
78 loader: 'babel-loader',
79 options: {
80 presets: [babelPreset],
81 cacheDirectory: settings.isDevelopment(),
82 babelrc: babelrcExists,
83 plugins: [babelrcExists ? null : require.resolve(settings.getHotLoaderName())]
84 }
85 }
86 ]
87 },
88 loaders.css.development,
89 loaders.scss.development,
90 loaders.fonts,
91 loaders.images,
92 loaders.eslint
93 ]
94 },
95 plugins: [
96 new webpack.DefinePlugin(settings.globals()),
97
98 new webpack.BannerPlugin({
99 banner: `APP_VERSION=${JSON.stringify(getVersion())};`,
100 test: /\.(js|mjs|jsx|ts|tsx)$/,
101 raw: true,
102 entryOnly: true
103 }),
104
105 new webpack.BannerPlugin({
106 banner: `v${getVersion()} - ${new Date().toJSON()}`
107 }),
108
109 // Converts:
110 // [HMR] Updated modules:
111 // [HMR] - 5
112 // To:
113 // [HMR] Updated modules:
114 // [HMR] - ./src/middleware/api.js
115 new webpack.NamedModulesPlugin(),
116
117 // Generate hot module chunks
118 new webpack.HotModuleReplacementPlugin(),
119
120 new HtmlWebpackPlugin(html(settings)),
121
122 new DuplicatePackageCheckerPlugin({
123 verbose: true,
124 exclude(instance) {
125 return instance.name === 'regenerator-runtime';
126 }
127 }),
128
129 // Ignore all the moment local files
130 new webpack.IgnorePlugin(/^\.\/locale$/, /moment$/),
131
132 new CaseSensitivePathsPlugin(),
133
134 new CopyWebpackPlugin(
135 [
136 {
137 context: `${settings.app()}/static`, // copy from this directory
138 from: '**/*', // copy all files
139 to: 'static' // copy into {output}/static folder
140 }
141 ],
142 {
143 logLevel: 'warn'
144 }
145 )
146 ]
147 };
148
149 if (settings.getHotLoaderName() === 'react-refresh/babel') {
150 config.plugins.push(
151 new ReactRefreshWebpackPlugin({
152 disableRefreshCheck: true
153 })
154 );
155 }
156
157 if (settings.isNotifications()) {
158 config.plugins.push(
159 new WebpackNotifierPlugin({
160 contentImage: path.join(__dirname, './public/availity.png'),
161 excludeWarnings: true
162 })
163 );
164 }
165
166 return config;
167};
168
169module.exports = plugin;