Try to optimize frontend
[oweals/peertube.git] / client / config / webpack.common.js
1 const helpers = require('./helpers')
2
3 /*
4  * Webpack Plugins
5  */
6
7 const AssetsPlugin = require('assets-webpack-plugin')
8 const ContextReplacementPlugin = require('webpack/lib/ContextReplacementPlugin')
9 const CommonsChunkPlugin = require('webpack/lib/optimize/CommonsChunkPlugin')
10 const CheckerPlugin = require('awesome-typescript-loader').CheckerPlugin
11 const HtmlWebpackPlugin = require('html-webpack-plugin')
12 const LoaderOptionsPlugin = require('webpack/lib/LoaderOptionsPlugin')
13 const ScriptExtHtmlWebpackPlugin = require('script-ext-html-webpack-plugin')
14 const InlineManifestWebpackPlugin = require('inline-manifest-webpack-plugin')
15 const ngcWebpack = require('ngc-webpack')
16
17 const WebpackNotifierPlugin = require('webpack-notifier')
18
19 const HMR = helpers.hasProcessFlag('hot')
20 const AOT = process.env.BUILD_AOT || helpers.hasNpmFlag('aot')
21 const METADATA = {
22   title: 'PeerTube',
23   baseUrl: '/',
24   isDevServer: helpers.isWebpackDevServer(),
25   HMR: HMR,
26   AOT: AOT
27 }
28
29 /*
30  * Webpack configuration
31  *
32  * See: http://webpack.github.io/docs/configuration.html#cli
33  */
34 module.exports = function (options) {
35   const isProd = options.env === 'production'
36   const AOT = isProd
37
38   return {
39
40     /*
41      * Cache generated modules and chunks to improve performance for multiple incremental builds.
42      * This is enabled by default in watch mode.
43      * You can pass false to disable it.
44      *
45      * See: http://webpack.github.io/docs/configuration.html#cache
46      */
47     // cache: false,
48
49     /*
50      * The entry point for the bundle
51      * Our Angular.js app
52      *
53      * See: http://webpack.github.io/docs/configuration.html#entry
54      */
55     entry: {
56       'polyfills': './src/polyfills.browser.ts',
57       'main': AOT
58               ? './src/main.browser.aot.ts'
59               : './src/main.browser.ts'
60     },
61
62     /*
63      * Options affecting the resolving of modules.
64      *
65      * See: http://webpack.github.io/docs/configuration.html#resolve
66      */
67     resolve: {
68       /*
69        * An array of extensions that should be used to resolve modules.
70        *
71        * See: http://webpack.github.io/docs/configuration.html#resolve-extensions
72        */
73       extensions: [ '.ts', '.js', '.json', '.scss' ],
74
75       modules: [ helpers.root('src'), helpers.root('node_modules') ]
76     },
77
78     /*
79      * Options affecting the normal modules.
80      *
81      * See: http://webpack.github.io/docs/configuration.html#module
82      */
83     module: {
84
85       rules: [
86
87         /*
88          * Typescript loader support for .ts and Angular async routes via .async.ts
89          *
90          * See: https://github.com/s-panferov/awesome-typescript-loader
91          */
92         {
93           test: /\.ts$/,
94           use: [
95             {
96               loader: 'ng-router-loader',
97               options: {
98                 loader: 'async-import',
99                 genDir: 'compiled',
100                 aot: AOT
101               }
102             },
103             {
104               loader: 'awesome-typescript-loader',
105               options: {
106                 configFileName: 'tsconfig.webpack.json',
107                 useCache: !isProd
108               }
109             },
110             {
111               loader: 'angular2-template-loader'
112             }
113           ],
114           exclude: [/\.(spec|e2e)\.ts$/]
115         },
116
117         /*
118          * Json loader support for *.json files.
119          *
120          * See: https://github.com/webpack/json-loader
121          */
122         {
123           test: /\.json$/,
124           use: 'json-loader'
125         },
126
127         {
128           test: /\.(sass|scss)$/,
129           use: [
130             'css-to-string-loader',
131             {
132               loader: 'css-loader',
133               options: {
134                 sourceMap: true,
135                 importLoaders: 1
136               }
137             },
138             'resolve-url-loader',
139             {
140               loader: 'sass-loader',
141               options: {
142                 sourceMap: true
143               }
144             },
145             {
146               loader: 'sass-resources-loader',
147               options: {
148                 resources: [
149                   helpers.root('src/sass/_variables.scss')
150                 ]
151               }
152             }
153           ]
154         },
155         { test: /\.woff(2)?(\?v=[0-9]\.[0-9]\.[0-9])?$/, use: 'url-loader?limit=10000&minetype=application/font-woff' },
156         { test: /\.(ttf|eot|svg)(\?v=[0-9]\.[0-9]\.[0-9])?$/, use: 'file-loader' },
157
158         /* Raw loader support for *.html
159          * Returns file content as string
160          *
161          * See: https://github.com/webpack/raw-loader
162          */
163         {
164           test: /\.html$/,
165           use: 'raw-loader',
166           exclude: [
167             helpers.root('src/index.html'),
168             helpers.root('src/standalone/videos/embed.html')
169           ]
170         },
171
172         /* File loader for supporting images, for example, in CSS files.
173          */
174         {
175           test: /\.(jpg|png|gif)$/,
176           use: 'url-loader'
177         }
178
179       ]
180
181     },
182
183     /*
184      * Add additional plugins to the compiler.
185      *
186      * See: http://webpack.github.io/docs/configuration.html#plugins
187      */
188     plugins: [
189       new AssetsPlugin({
190         path: helpers.root('dist'),
191         filename: 'webpack-assets.json',
192         prettyPrint: true
193       }),
194
195       /*
196        * Plugin: ForkCheckerPlugin
197        * Description: Do type checking in a separate process, so webpack don't need to wait.
198        *
199        * See: https://github.com/s-panferov/awesome-typescript-loader#forkchecker-boolean-defaultfalse
200        */
201       new CheckerPlugin(),
202
203       /*
204        * Plugin: CommonsChunkPlugin
205        * Description: Shares common code between the pages.
206        * It identifies common modules and put them into a commons chunk.
207        *
208        * See: https://webpack.github.io/docs/list-of-plugins.html#commonschunkplugin
209        * See: https://github.com/webpack/docs/wiki/optimization#multi-page-app
210        */
211       new CommonsChunkPlugin({
212         name: 'polyfills',
213         chunks: ['polyfills']
214       }),
215
216       // This enables tree shaking of the vendor modules
217       new CommonsChunkPlugin({
218         name: 'vendor',
219         chunks: ['main'],
220         minChunks: module => {
221           return /node_modules\//.test(module.resource)
222         }
223       }),
224
225       // Specify the correct order the scripts will be injected in
226       new CommonsChunkPlugin({
227         name: ['polyfills', 'vendor'].reverse()
228       }),
229
230       /**
231        * Plugin: ContextReplacementPlugin
232        * Description: Provides context to Angular's use of System.import
233        *
234        * See: https://webpack.github.io/docs/list-of-plugins.html#contextreplacementplugin
235        * See: https://github.com/angular/angular/issues/11580
236        */
237       new ContextReplacementPlugin(
238         /**
239          * The (\\|\/) piece accounts for path separators in *nix and Windows
240          */
241         /(.+)?angular(\\|\/)core(.+)?/,
242         helpers.root('src'), // location of your src
243         {
244           /**
245            * Your Angular Async Route paths relative to this root directory
246            */
247         }
248       ),
249
250       /*
251        * Plugin: HtmlWebpackPlugin
252        * Description: Simplifies creation of HTML files to serve your webpack bundles.
253        * This is especially useful for webpack bundles that include a hash in the filename
254        * which changes every compilation.
255        *
256        * See: https://github.com/ampedandwired/html-webpack-plugin
257        */
258       new HtmlWebpackPlugin({
259         template: 'src/index.html',
260         title: METADATA.title,
261         chunksSortMode: function (a, b) {
262           const entryPoints = [ 'inline', 'polyfills', 'sw-register', 'styles', 'vendor', 'main' ]
263           return entryPoints.indexOf(a.names[0]) - entryPoints.indexOf(b.names[0])
264         },
265         metadata: METADATA,
266         inject: 'body'
267       }),
268
269       /*
270        * Plugin: ScriptExtHtmlWebpackPlugin
271        * Description: Enhances html-webpack-plugin functionality
272        * with different deployment options for your scripts including:
273        *
274        * See: https://github.com/numical/script-ext-html-webpack-plugin
275        */
276       new ScriptExtHtmlWebpackPlugin({
277         sync: [ /polyfill|vendor/ ],
278         defaultAttribute: 'async',
279         preload: [/polyfill|vendor|main/],
280         prefetch: [/chunk/]
281       }),
282
283       new WebpackNotifierPlugin({ alwaysNotify: true }),
284
285       /**
286       * Plugin LoaderOptionsPlugin (experimental)
287       *
288       * See: https://gist.github.com/sokra/27b24881210b56bbaff7
289       */
290       new LoaderOptionsPlugin({
291         options: {
292           sassLoader: {
293             precision: 10,
294             includePaths: [ helpers.root('src/sass') ]
295           }
296         }
297       }),
298
299       new ngcWebpack.NgcWebpackPlugin({
300         disabled: !AOT,
301         tsConfig: helpers.root('tsconfig.webpack.json')
302       }),
303
304       new InlineManifestWebpackPlugin(),
305     ],
306
307     /*
308      * Include polyfills or mocks for various node stuff
309      * Description: Node configuration
310      *
311      * See: https://webpack.github.io/docs/configuration.html#node
312      */
313     node: {
314       global: true,
315       crypto: 'empty',
316       process: true,
317       module: false,
318       clearImmediate: false,
319       setImmediate: false,
320       setInterval: false,
321       setTimeout: false
322     }
323   }
324 }