webpack.config.js 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238
  1. /* eslint-disable @typescript-eslint/camelcase */
  2. /* eslint-disable @typescript-eslint/no-var-requires */
  3. // Copyright 2017-2019 @polkadot/apps authors & contributors
  4. // This software may be modified and distributed under the terms
  5. // of the Apache-2.0 license. See the LICENSE file for details.
  6. const fs = require('fs');
  7. const path = require('path');
  8. const webpack = require('webpack');
  9. const CopyWebpackPlugin = require('copy-webpack-plugin');
  10. const MiniCssExtractPlugin = require('mini-css-extract-plugin');
  11. const HtmlWebpackPlugin = require('html-webpack-plugin');
  12. const { WebpackPluginServe } = require('webpack-plugin-serve');
  13. const findPackages = require('../../scripts/findPackages'); // Do we need to add joy- apps in that script?
  14. const DEFAULT_THEME = 'substrate';
  15. const ENV = process.env.NODE_ENV || 'development';
  16. function createWebpack ({ alias = {}, context, name = 'index' }) {
  17. const pkgJson = require(path.join(context, 'package.json'));
  18. const isProd = ENV === 'production';
  19. const hasPublic = fs.existsSync(path.join(context, 'public'));
  20. const plugins = hasPublic
  21. ? [new CopyWebpackPlugin([{ from: 'public' }])]
  22. : [];
  23. // disabled, smooths dev load, was -
  24. // isProd ? 'source-map' : 'cheap-eval-source-map',
  25. const devtool = false;
  26. return {
  27. context,
  28. devtool,
  29. entry: [
  30. '@babel/polyfill',
  31. `./src/${name}.tsx`,
  32. isProd
  33. ? null
  34. : null // 'webpack-plugin-serve/client'
  35. ].filter((entry) => entry),
  36. mode: ENV,
  37. output: {
  38. chunkFilename: '[name].[chunkhash:8].js',
  39. filename: '[name].[hash:8].js',
  40. globalObject: '(typeof self !== \'undefined\' ? self : this)',
  41. path: path.join(context, 'build')
  42. },
  43. resolve: {
  44. alias,
  45. extensions: ['.js', '.jsx', '.ts', '.tsx']
  46. },
  47. module: {
  48. rules: [
  49. {
  50. test: /\.css$/,
  51. exclude: /(node_modules)/,
  52. use: [
  53. isProd
  54. ? MiniCssExtractPlugin.loader
  55. : require.resolve('style-loader'),
  56. {
  57. loader: require.resolve('css-loader'),
  58. options: {
  59. importLoaders: 1
  60. }
  61. },
  62. {
  63. loader: require.resolve('postcss-loader'),
  64. options: {
  65. ident: 'postcss',
  66. plugins: () => [
  67. require('precss'),
  68. require('autoprefixer'),
  69. require('postcss-simple-vars'),
  70. require('postcss-nested'),
  71. require('postcss-import'),
  72. require('postcss-clean')(),
  73. require('postcss-flexbugs-fixes')
  74. ]
  75. }
  76. }
  77. ]
  78. },
  79. {
  80. test: /\.s[ac]ss$/i,
  81. use: [
  82. // Creates `style` nodes from JS strings
  83. 'style-loader',
  84. // Translates CSS into CommonJS
  85. 'css-loader',
  86. // Compiles Sass to CSS
  87. 'sass-loader'
  88. ]
  89. },
  90. {
  91. test: /\.less$/,
  92. loaders: ['style-loader', 'css-loader', 'less-loader']
  93. },
  94. {
  95. test: /\.css$/,
  96. include: /node_modules/,
  97. use: [
  98. isProd
  99. ? MiniCssExtractPlugin.loader
  100. : require.resolve('style-loader'),
  101. require.resolve('css-loader')
  102. ]
  103. },
  104. {
  105. test: /\.(js|ts|tsx)$/,
  106. exclude: /(node_modules)/,
  107. use: [
  108. require.resolve('thread-loader'),
  109. {
  110. loader: require.resolve('babel-loader'),
  111. options: require('@polkadot/dev-react/config/babel')
  112. }
  113. ]
  114. },
  115. {
  116. test: /\.md$/,
  117. use: [
  118. require.resolve('html-loader'),
  119. require.resolve('markdown-loader')
  120. ]
  121. },
  122. {
  123. test: [/\.bmp$/, /\.gif$/, /\.jpe?g$/, /\.png$/],
  124. use: [
  125. {
  126. loader: require.resolve('url-loader'),
  127. options: {
  128. limit: 10000,
  129. name: 'static/[name].[hash:8].[ext]'
  130. }
  131. }
  132. ]
  133. },
  134. {
  135. test: [/\.eot$/, /\.ttf$/, /\.svg$/, /\.woff$/, /\.woff2$/],
  136. use: [
  137. {
  138. loader: require.resolve('file-loader'),
  139. options: {
  140. name: 'static/[name].[hash:8].[ext]'
  141. }
  142. }
  143. ]
  144. }
  145. ]
  146. },
  147. node: {
  148. child_process: 'empty',
  149. dgram: 'empty',
  150. fs: 'empty',
  151. net: 'empty',
  152. tls: 'empty'
  153. },
  154. optimization: {
  155. runtimeChunk: 'single',
  156. splitChunks: {
  157. cacheGroups: {
  158. vendorOther: {
  159. chunks: 'initial',
  160. enforce: true,
  161. name: 'vendor',
  162. test: /node_modules\/(asn1|bn\.js|buffer|cuint|elliptic|lodash|moment|readable-stream|rxjs)/
  163. },
  164. vendorReact: {
  165. chunks: 'initial',
  166. enforce: true,
  167. name: 'react',
  168. test: /node_modules\/(chart|i18next|react|semantic-ui)/
  169. },
  170. polkadotJs: {
  171. chunks: 'initial',
  172. enforce: true,
  173. name: 'polkadotjs',
  174. test: /node_modules\/(@polkadot\/wasm-(crypto|dalek-ed25519|schnorrkel))/
  175. }
  176. }
  177. }
  178. },
  179. performance: {
  180. hints: false
  181. },
  182. plugins: plugins.concat([
  183. new webpack.IgnorePlugin(/^\.\/locale$/, /moment$/),
  184. new webpack.DefinePlugin({
  185. 'process.env': {
  186. NODE_ENV: JSON.stringify(ENV),
  187. VERSION: JSON.stringify(pkgJson.version),
  188. UI_MODE: JSON.stringify(process.env.UI_MODE || 'light'),
  189. UI_THEME: JSON.stringify(process.env.UI_THEME || DEFAULT_THEME),
  190. WS_URL: JSON.stringify(process.env.WS_URL)
  191. }
  192. }),
  193. new HtmlWebpackPlugin({
  194. inject: true,
  195. template: path.join(context, `${hasPublic ? 'public/' : ''}${name}.html`),
  196. IS_PROD: isProd,
  197. PAGE_TITLE: process.env.UI_THEME === 'substrate'
  198. ? 'Joystream Network Portal'
  199. : 'Joystream Network Portal'
  200. }),
  201. new webpack.optimize.SplitChunksPlugin(),
  202. new MiniCssExtractPlugin({
  203. filename: '[name].[contenthash:8].css'
  204. }),
  205. isProd
  206. ? null
  207. : new WebpackPluginServe({
  208. hmr: false, // switch off, Chrome WASM memory leak
  209. liveReload: false, // explict off, overrides hmr
  210. progress: false, // since we have hmr off, disable
  211. port: 3000,
  212. static: path.join(process.cwd(), '/build')
  213. })
  214. ]).filter((plugin) => plugin),
  215. watch: !isProd
  216. };
  217. }
  218. module.exports = createWebpack({
  219. context: __dirname,
  220. alias: {
  221. ...(
  222. findPackages().reduce((alias, { dir, name }) => {
  223. alias[name] = path.resolve(__dirname, `../${dir}/src`);
  224. return alias;
  225. }, {})
  226. ),
  227. // TODO: Me might try to add it to "findPackages", but this will be a little more tricky
  228. '@joystream/types': path.resolve(__dirname, '../../../types/src')
  229. }
  230. });