1 | import fs from 'fs'
|
2 | import merge from 'webpack-merge'
|
3 | import MiniCssExtractPlugin from 'mini-css-extract-plugin'
|
4 | import path from 'path'
|
5 | import TerserPlugin from 'terser-webpack-plugin'
|
6 | import webpack from 'webpack'
|
7 |
|
8 | const config = customizations => {
|
9 | const mode = process.env.NODE_ENV
|
10 |
|
11 | const tsScriptConfigPath = fs.existsSync(`${process.cwd()}/tsconfig.json`)
|
12 | ? `${process.cwd()}/tsconfig.json`
|
13 | : path.resolve('node_modules', '@procore', 'core-webpack', 'tsconfig.json')
|
14 |
|
15 | const output =
|
16 | mode === 'production'
|
17 | ? {
|
18 | path: path.resolve(`${process.cwd()}`, 'build'),
|
19 | filename: '[name].bundle.js',
|
20 | libraryTarget: 'umd',
|
21 | }
|
22 | : {
|
23 | path: '/',
|
24 | publicPath: 'http://localhost:5000/',
|
25 | filename: '[name].bundle.js',
|
26 | libraryTarget: 'umd',
|
27 | }
|
28 |
|
29 | let plugins = [
|
30 | new MiniCssExtractPlugin({
|
31 | filename: '[name].bundle.css',
|
32 | }),
|
33 | ]
|
34 |
|
35 | const client = process.env.CLIENT_NAME ? `-${process.env.CLIENT_NAME}` : ''
|
36 | const digest = process.env.CLIENT_DIGEST
|
37 | ? `-${process.env.CLIENT_DIGEST}`
|
38 | : ''
|
39 |
|
40 | plugins =
|
41 | mode === 'development'
|
42 | ? plugins
|
43 | : plugins.concat([
|
44 | new webpack.SourceMapDevToolPlugin({
|
45 | test: /\.js$/,
|
46 | filename: `sourcemaps/[name].bundle${client}${digest}.js.map`,
|
47 | append: false,
|
48 | exclude: [/node_modules\/*/],
|
49 | }),
|
50 | new webpack.SourceMapDevToolPlugin({
|
51 | test: /\.css$/,
|
52 | filename: '[file].map',
|
53 | exclude: [/node_modules\/*/],
|
54 | }),
|
55 | ])
|
56 |
|
57 | const defaults = {
|
58 | entry: {
|
59 | index: path.resolve('src', 'index.js'),
|
60 | },
|
61 |
|
62 | devServer: {
|
63 | headers: {
|
64 | 'Access-Control-Allow-Origin': '*',
|
65 | },
|
66 | host: '0.0.0.0',
|
67 | hot: true,
|
68 | inline: true,
|
69 | port: '5000',
|
70 | },
|
71 |
|
72 | devtool: mode === 'production' ? false : 'inline-source-map',
|
73 |
|
74 | mode,
|
75 |
|
76 | module: {
|
77 | rules: [
|
78 | {
|
79 | test: /\.tsx?$/,
|
80 | exclude: /node_modules/,
|
81 | use: {
|
82 | loader: require.resolve('ts-loader'),
|
83 | options: {
|
84 | context: process.cwd(),
|
85 | configFile: tsScriptConfigPath,
|
86 | },
|
87 | },
|
88 | },
|
89 | {
|
90 | test: /\.jsx?$/,
|
91 | exclude: /node_modules/,
|
92 | use: {
|
93 | loader: require.resolve('babel-loader'),
|
94 | options: {
|
95 | plugins: [
|
96 | require.resolve('@babel/plugin-proposal-object-rest-spread'),
|
97 | require.resolve('@babel/plugin-transform-runtime'),
|
98 | require.resolve('babel-plugin-transform-class-properties'),
|
99 | ],
|
100 | presets: [
|
101 | require.resolve('@babel/preset-env'),
|
102 | require.resolve('@babel/preset-react'),
|
103 | ],
|
104 | },
|
105 | },
|
106 | },
|
107 | {
|
108 | test: /\.s?[ca]ss$/,
|
109 | exclude: /node_modules/,
|
110 | use: [
|
111 | {
|
112 | loader:
|
113 | mode === 'development'
|
114 | ? require.resolve('style-loader')
|
115 | : MiniCssExtractPlugin.loader,
|
116 | },
|
117 | {
|
118 | loader: require.resolve('css-loader'),
|
119 | options: {
|
120 | localIdentName: '[local]--[hash:base64:5]',
|
121 | modules: true,
|
122 | importLoaders: 1,
|
123 | },
|
124 | },
|
125 | {
|
126 | loader: require.resolve('postcss-loader'),
|
127 | options: {
|
128 | ident: 'postcss',
|
129 | plugins: () => [
|
130 | require('postcss-preset-env')({
|
131 | browsers: 'last 2 versions',
|
132 | }),
|
133 | require('precss')(),
|
134 | ],
|
135 | },
|
136 | },
|
137 | ],
|
138 | },
|
139 | {
|
140 | test: /\.(gif|jpe?g|png|svg|eot|ttf|otf|woff2?)$/,
|
141 | use: require.resolve('file-loader'),
|
142 | },
|
143 | ],
|
144 | },
|
145 |
|
146 | optimization: {
|
147 | minimizer: [
|
148 | new TerserPlugin({
|
149 | cache: true,
|
150 | parallel: 2,
|
151 | sourceMap: true,
|
152 | terserOptions: {
|
153 | compress: {
|
154 | drop_console: true,
|
155 | },
|
156 | },
|
157 | }),
|
158 | ],
|
159 | splitChunks: {
|
160 | cacheGroups: {
|
161 | default: {
|
162 | minChunks: 2,
|
163 | priority: -20,
|
164 | reuseExistingChunk: true,
|
165 | },
|
166 | styles: {
|
167 | chunks: 'all',
|
168 | enforce: true,
|
169 | name: 'styles',
|
170 | test: /\.css$/,
|
171 | },
|
172 | vendors: {
|
173 | test: /[\\/]node_modules[\\/]/,
|
174 | priority: -10,
|
175 | },
|
176 | },
|
177 | },
|
178 | },
|
179 |
|
180 | output,
|
181 |
|
182 | plugins,
|
183 |
|
184 | resolve: {
|
185 | extensions: ['.css', '.js', '.jsx', '.scss', '.ts', '.tsx'],
|
186 | },
|
187 | }
|
188 |
|
189 | return typeof customizations === 'function'
|
190 | ? customizations(merge, defaults)
|
191 | : merge(defaults, customizations)
|
192 | }
|
193 |
|
194 | exports = module.exports = config
|