diff options
Diffstat (limited to 'subprojects/frontend/webpack.config.js')
-rw-r--r-- | subprojects/frontend/webpack.config.js | 164 |
1 files changed, 164 insertions, 0 deletions
diff --git a/subprojects/frontend/webpack.config.js b/subprojects/frontend/webpack.config.js new file mode 100644 index 00000000..bacb7e4a --- /dev/null +++ b/subprojects/frontend/webpack.config.js | |||
@@ -0,0 +1,164 @@ | |||
1 | const fs = require('fs'); | ||
2 | const path = require('path'); | ||
3 | |||
4 | const { DefinePlugin } = require('webpack'); | ||
5 | const HtmlWebpackPlugin = require('html-webpack-plugin'); | ||
6 | const HtmlWebpackInjectPreload = require('@principalstudio/html-webpack-inject-preload'); | ||
7 | const MiniCssExtractPlugin = require('mini-css-extract-plugin'); | ||
8 | const { SubresourceIntegrityPlugin } = require('webpack-subresource-integrity'); | ||
9 | |||
10 | const packageInfo = require('./package.json'); | ||
11 | |||
12 | const currentNodeEnv = process.env.NODE_ENV || 'development'; | ||
13 | const devMode = currentNodeEnv !== 'production'; | ||
14 | const outputPath = path.resolve(__dirname, 'build/webpack', currentNodeEnv); | ||
15 | |||
16 | function portNumberOrElse (envName, fallback) { | ||
17 | const value = process.env[envName]; | ||
18 | return value ? parseInt(value) : fallback; | ||
19 | } | ||
20 | |||
21 | const listenHost = process.env['LISTEN_HOST'] || 'localhost'; | ||
22 | const listenPort = portNumberOrElse('LISTEN_PORT', 1313); | ||
23 | const apiHost = process.env['API_HOST'] || listenHost; | ||
24 | const apiPort = portNumberOrElse('API_PORT', 1312); | ||
25 | const publicHost = process.env['PUBLIC_HOST'] || listenHost; | ||
26 | const publicPort = portNumberOrElse('PUBLIC_PORT', listenPort); | ||
27 | |||
28 | module.exports = { | ||
29 | mode: devMode ? 'development' : 'production', | ||
30 | entry: './src/index', | ||
31 | output: { | ||
32 | path: outputPath, | ||
33 | publicPath: '/', | ||
34 | filename: devMode ? '[name].js' : '[name].[contenthash].js', | ||
35 | assetModuleFilename: devMode ? '[name][ext]' : '[name].[contenthash][ext]', | ||
36 | clean: true, | ||
37 | crossOriginLoading: 'anonymous', | ||
38 | }, | ||
39 | module: { | ||
40 | rules: [ | ||
41 | { | ||
42 | test: /.[jt]sx?$/i, | ||
43 | include: [path.resolve(__dirname, 'src')], | ||
44 | use: [ | ||
45 | { | ||
46 | loader: 'babel-loader', | ||
47 | options: { | ||
48 | presets: [ | ||
49 | [ | ||
50 | '@babel/preset-env', | ||
51 | { | ||
52 | targets: 'defaults', | ||
53 | }, | ||
54 | ], | ||
55 | '@babel/preset-react', | ||
56 | [ | ||
57 | '@babel/preset-typescript', | ||
58 | { | ||
59 | isTSX: true, | ||
60 | allExtensions: true, | ||
61 | allowDeclareFields: true, | ||
62 | onlyRemoveTypeImports: true, | ||
63 | optimizeConstEnums: true, | ||
64 | }, | ||
65 | ] | ||
66 | ], | ||
67 | plugins: [ | ||
68 | '@babel/plugin-transform-runtime', | ||
69 | ], | ||
70 | }, | ||
71 | }, | ||
72 | ], | ||
73 | }, | ||
74 | { | ||
75 | test: /\.scss$/i, | ||
76 | use: [ | ||
77 | devMode ? 'style-loader' : MiniCssExtractPlugin.loader, | ||
78 | 'css-loader', | ||
79 | { | ||
80 | loader: 'sass-loader', | ||
81 | options: { | ||
82 | implementation: require.resolve('sass'), | ||
83 | }, | ||
84 | }, | ||
85 | ], | ||
86 | }, | ||
87 | { | ||
88 | test: /\.(gif|png|jpe?g|svg?)$/i, | ||
89 | use: [ | ||
90 | { | ||
91 | loader: 'image-webpack-loader', | ||
92 | options: { | ||
93 | disable: true, | ||
94 | } | ||
95 | }, | ||
96 | ], | ||
97 | type: 'asset', | ||
98 | }, | ||
99 | { | ||
100 | test: /\.woff2?$/i, | ||
101 | type: 'asset/resource', | ||
102 | }, | ||
103 | ], | ||
104 | }, | ||
105 | resolve: { | ||
106 | extensions: ['.ts', '.tsx', '.js', '.jsx'], | ||
107 | }, | ||
108 | devtool: devMode ? 'inline-source-map' : 'source-map', | ||
109 | optimization: { | ||
110 | providedExports: !devMode, | ||
111 | sideEffects: devMode ? 'flag' : true, | ||
112 | splitChunks: { | ||
113 | chunks: 'all', | ||
114 | }, | ||
115 | }, | ||
116 | devServer: { | ||
117 | client: { | ||
118 | logging: 'info', | ||
119 | overlay: true, | ||
120 | progress: true, | ||
121 | webSocketURL: { | ||
122 | hostname: publicHost, | ||
123 | port: publicPort, | ||
124 | protocol: publicPort === 443 ? 'wss' : 'ws', | ||
125 | }, | ||
126 | }, | ||
127 | compress: true, | ||
128 | host: listenHost, | ||
129 | port: listenPort, | ||
130 | proxy: { | ||
131 | '/xtext-service': { | ||
132 | target: `${apiPort === 443 ? 'https' : 'http'}://${apiHost}:${apiPort}`, | ||
133 | ws: true, | ||
134 | }, | ||
135 | }, | ||
136 | }, | ||
137 | plugins: [ | ||
138 | new DefinePlugin({ | ||
139 | 'DEBUG': JSON.stringify(devMode), | ||
140 | 'PACKAGE_NAME': JSON.stringify(packageInfo.name), | ||
141 | 'PACKAGE_VERSION': JSON.stringify(packageInfo.version), | ||
142 | }), | ||
143 | new MiniCssExtractPlugin({ | ||
144 | filename: '[name].[contenthash].css', | ||
145 | chunkFilename: '[name].[contenthash].css', | ||
146 | }), | ||
147 | new SubresourceIntegrityPlugin(), | ||
148 | new HtmlWebpackPlugin({ | ||
149 | template: 'src/index.html', | ||
150 | }), | ||
151 | new HtmlWebpackInjectPreload({ | ||
152 | files: [ | ||
153 | { | ||
154 | match: /(roboto-latin-(400|500)-normal|jetbrains-mono-latin-variable).*\.woff2/, | ||
155 | attributes: { | ||
156 | as: 'font', | ||
157 | type: 'font/woff2', | ||
158 | crossorigin: 'anonymous', | ||
159 | }, | ||
160 | }, | ||
161 | ], | ||
162 | }), | ||
163 | ], | ||
164 | }; | ||