-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathwebpack.config.js
296 lines (282 loc) · 10.6 KB
/
webpack.config.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
const path = require('path');
const webpack = require('webpack');
const TerserPlugin = require('terser-webpack-plugin');
const ReactNative = require('@callstack/repack');
/**
* More documentation, installation, usage, motivation and differences with Metro is available at:
* https://github.com/callstack/repack/blob/main/README.md
*
* The API documentation for the functions and plugins used in this file is available at:
* https://re-pack.netlify.app/
*/
/**
* This is the Webpack configuration file for your React Native project.
* It can be used in 2 ways:
* - by running React Native CLI eg: `npx react-native start` or `npx react-native bundle`
* - by running Webpack CLI eg: `PLATFORM=(ios|android) npx webpack-cli -c webpack.config.js`
*
* Depending on which option you chose the output might be different, since when running with
* React Native CLI most of the values from `getMode`, `getPlatform`, etc. will be filled in by React Native CLI.
* However, when running with Webpack CLI, you might want to tweak `fallback` values to your liking.
*
* Please refer to the API documentation for list of options, plugins and their descriptions.
*/
/**
* Get options from React Native CLI when Webpack is run from `react-native start` or `react-native bundle`.
*
* If you run Webpack using Webpack CLI, the values from `fallback` will be used - use it
* to specify your values, if the defaults don't suit your project.
*/
const mode = ReactNative.getMode({fallback: 'development'});
const dev = mode === 'development';
const context = ReactNative.getContext();
const entry = ReactNative.getEntry();
const platform = ReactNative.getPlatform({fallback: process.env.PLATFORM});
const minimize = ReactNative.isMinimizeEnabled({fallback: !dev});
const devServer = ReactNative.getDevServerOptions();
const reactNativePath = ReactNative.getReactNativePath();
/**
* Depending on your Babel configuration you might want to keep it.
* If you don't use `env` in your Babel config, you can remove it.
*
* Keep in mind that if you remove it you should set `BABEL_ENV` or `NODE_ENV`
* to `development` or `production`. Otherwise your production code might be compiled with
* in development mode by Babel.
*/
process.env.BABEL_ENV = mode;
/**
* Webpack configuration.
*/
module.exports = {
mode,
/**
* This should be always `false`, since the Source Map configuration is done
* by `SourceMapDevToolPlugin`.
*/
devtool: false,
context,
/**
* `getInitializationEntries` will return necessary entries with setup and initialization code.
* If you don't want to use Hot Module Replacement, set `hmr` option to `false`. By default,
* HMR will be enabled in development mode.
*/
entry: [
...ReactNative.getInitializationEntries(reactNativePath, {
hmr: devServer.hmr,
}),
entry,
],
resolve: {
/**
* `getResolveOptions` returns additional resolution configuration for React Native.
* If it's removed, you won't be able to use `<file>.<platform>.<ext>` (eg: `file.ios.js`)
* convention and some 3rd-party libraries that specify `react-native` field
* in their `package.json` might not work correctly.
*/
...ReactNative.getResolveOptions(platform),
/**
* Uncomment this to ensure all `react-native*` imports will resolve to the same React Native
* dependency. You might need it when using workspaces/monorepos or unconventional project
* structure. For simple/typical project you won't need it.
*/
// alias: {
// 'react-native': reactNativePath,
// },
},
/**
* Configures output.
* It's recommended to leave it as it is unless you know what you're doing.
* By default Webpack will emit files into the directory specified under `path`. In order for the
* React Native app use them when bundling the `.ipa`/`.apk`, they need to be copied over with
* `ReactNative.OutputPlugin`, which is configured by default.
*/
output: {
clean: true,
path: path.join(__dirname, 'build', platform),
filename: 'index.bundle',
chunkFilename: '[name].chunk.bundle',
publicPath: ReactNative.getPublicPath(devServer),
},
/**
* Configures optimization of the built bundle.
*/
optimization: {
/** Enables minification based on values passed from React Native CLI or from fallback. */
minimize,
/** Configure minimizer to process the bundle. */
minimizer: [
new TerserPlugin({
test: /\.(js)?bundle(\?.*)?$/i,
/**
* Prevents emitting text file with comments, licenses etc.
* If you want to gather in-file licenses, feel free to remove this line or configure it
* differently.
*/
extractComments: false,
}),
],
},
module: {
/**
* This rule will process all React Native related dependencies with Babel.
* If you have a 3rd-party dependency that you need to transpile, you can add it to the
* `include` list.
*
* You can also enable persistent caching with `cacheDirectory` - please refer to:
* https://github.com/babel/babel-loader#options
*/
rules: [
{
test: /\.[jt]sx?$/,
include: [
/node_modules(.*[/\\])+react/,
/node_modules(.*[/\\])+@react-native/,
/node_modules(.*[/\\])+@react-navigation/,
/node_modules(.*[/\\])+@react-native-community/,
/node_modules(.*[/\\])+@expo/,
/node_modules(.*[/\\])+pretty-format/,
/node_modules(.*[/\\])+metro/,
/node_modules(.*[/\\])+abort-controller/,
/node_modules(.*[/\\])+@callstack[/\\]repack/,
],
use: 'babel-loader',
},
/**
* Here you can adjust loader that will process your files.
*
* You can also enable persistent caching with `cacheDirectory` - please refer to:
* https://github.com/babel/babel-loader#options
*/
{
test: /\.[jt]sx?$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader',
options: {
/** Add React Refresh transform only when HMR is enabled. */
plugins: devServer.hmr ? ['module:react-refresh/babel'] : undefined,
},
},
},
/**
* This loader handles all static assets (images, video, audio and others), so that you can
* use (reference) them inside your application.
*
* If you wan to handle specific asset type manually, filter out the extension
* from `ASSET_EXTENSIONS`, for example:
* ```
* ReactNative.ASSET_EXTENSIONS.filter((ext) => ext !== 'svg')
* ```
*/
{
test: ReactNative.getAssetExtensionsRegExp(
ReactNative.ASSET_EXTENSIONS,
),
use: {
loader: '@callstack/repack/assets-loader',
options: {
platform,
devServerEnabled: devServer.enabled,
/**
* Defines which assets are scalable - which assets can have
* scale suffixes: `@1x`, `@2x` and so on.
* By default all images are scalable.
*/
scalableAssetExtensions: ReactNative.SCALABLE_ASSETS,
},
},
},
],
},
plugins: [
/**
* Various libraries like React and React rely on `process.env.NODE_ENV` / `__DEV__`
* to distinguish between production and development
*/
new webpack.DefinePlugin({
__DEV__: JSON.stringify(dev),
}),
/**
* This plugin makes sure the resolution for assets like images works with scales,
* for example: `[email protected]`, `[email protected]`.
*/
new ReactNative.AssetsResolverPlugin({
platform,
}),
/**
* React Native environment (globals and APIs that are available inside JS) differ greatly
* from Web or Node.js. This plugin ensures everything is setup correctly so that features
* like Hot Module Replacement will work correctly.
*/
new ReactNative.TargetPlugin(),
/**
* By default Webpack will emit files into `output.path` directory (eg: `<root>/build/ios`),
* but in order to for the React Native application to include those files (or a subset of those)
* they need to be copied over to correct output directories supplied from React Native CLI
* when bundling the code (with `webpack-bundle` command).
* In development mode (when development server is running), this plugin is a no-op.
*/
new ReactNative.OutputPlugin({
platform,
devServerEnabled: devServer.enabled,
}),
/**
* Runs development server when running with React Native CLI start command or if `devServer`
* was provided as s `fallback`.
*/
new ReactNative.DevServerPlugin({
platform,
...devServer,
}),
/**
* Configures Source Maps for the main bundle based on CLI options received from
* React Native CLI or fallback value..
* It's recommended to leave the default values, unless you know what you're doing.
* Wrong options might cause symbolication of stack trace inside React Native app
* to fail - the app will still work, but you might not get Source Map support.
*/
new webpack.SourceMapDevToolPlugin({
test: /\.(js)?bundle$/,
exclude: /\.chunk\.(js)?bundle$/,
filename: '[file].map',
append: `//# sourceMappingURL=[url]?platform=${platform}`,
/**
* Uncomment for faster builds but less accurate Source Maps
*/
// columns: false,
}),
/**
* Configures Source Maps for any additional chunks.
* It's recommended to leave the default values, unless you know what you're doing.
* Wrong options might cause symbolication of stack trace inside React Native app
* to fail - the app will still work, but you might not get Source Map support.
*/
new webpack.SourceMapDevToolPlugin({
test: /\.(js)?bundle$/,
include: /\.chunk\.(js)?bundle$/,
filename: '[file].map',
append: `//# sourceMappingURL=[url]?platform=${platform}`,
/**
* Uncomment for faster builds but less accurate Source Maps
*/
// columns: false,
}),
/**
* Logs messages and progress.
* It's recommended to always have this plugin, otherwise it might be difficult
* to figure out what's going on when bundling or running development server.
*/
new ReactNative.LoggerPlugin({
platform,
devServerEnabled: devServer.enabled,
output: {
console: true,
/**
* Uncomment for having logs stored in a file to this specific compilation.
* Compilation for each platform gets it's own log file.
*/
// file: path.join(__dirname, `${mode}.${platform}.log`),
},
}),
],
};