webpack.dev.js 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267
  1. const webpack = require('webpack')
  2. const path = require('path')
  3. const fs = require('fs-extra')
  4. const yargs = require('yargs').argv
  5. const _ = require('lodash')
  6. const { VueLoaderPlugin } = require('vue-loader')
  7. const CopyWebpackPlugin = require('copy-webpack-plugin')
  8. const HtmlWebpackPlugin = require('html-webpack-plugin')
  9. const HtmlWebpackPugPlugin = require('html-webpack-pug-plugin')
  10. const MomentTimezoneDataPlugin = require('moment-timezone-data-webpack-plugin')
  11. const VuetifyLoaderPlugin = require('vuetify-loader/lib/plugin')
  12. const WriteFilePlugin = require('write-file-webpack-plugin')
  13. const WebpackBarPlugin = require('webpackbar')
  14. const babelConfig = fs.readJsonSync(path.join(process.cwd(), '.babelrc'))
  15. const cacheDir = '.webpack-cache/cache'
  16. const babelDir = path.join(process.cwd(), '.webpack-cache/babel')
  17. process.noDeprecation = true
  18. fs.emptyDirSync(path.join(process.cwd(), 'assets-legacy'))
  19. module.exports = {
  20. mode: 'development',
  21. entry: {
  22. app: ['./client/index-app.js', 'webpack-hot-middleware/client']
  23. },
  24. output: {
  25. path: path.join(process.cwd(), 'assets-legacy'),
  26. publicPath: '/_assets-legacy/',
  27. filename: 'js/[name].js',
  28. chunkFilename: 'js/[name].js',
  29. globalObject: 'this',
  30. pathinfo: true,
  31. crossOriginLoading: 'use-credentials'
  32. },
  33. module: {
  34. rules: [
  35. {
  36. test: /\.js$/,
  37. exclude: (modulePath) => {
  38. return modulePath.includes('node_modules') && !modulePath.includes('vuetify')
  39. },
  40. use: [
  41. {
  42. loader: 'cache-loader',
  43. options: {
  44. cacheDirectory: cacheDir
  45. }
  46. },
  47. {
  48. loader: 'babel-loader',
  49. options: {
  50. ...babelConfig,
  51. cacheDirectory: babelDir
  52. }
  53. }
  54. ]
  55. },
  56. {
  57. test: /\.css$/,
  58. use: [
  59. 'style-loader',
  60. 'css-loader',
  61. 'postcss-loader'
  62. ]
  63. },
  64. {
  65. test: /\.sass$/,
  66. use: [
  67. {
  68. loader: 'cache-loader',
  69. options: {
  70. cacheDirectory: cacheDir
  71. }
  72. },
  73. 'style-loader',
  74. 'css-loader',
  75. 'postcss-loader',
  76. {
  77. loader: 'sass-loader',
  78. options: {
  79. implementation: require('sass'),
  80. sourceMap: false,
  81. sassOptions: {
  82. fiber: false
  83. }
  84. }
  85. }
  86. ]
  87. },
  88. {
  89. test: /\.scss$/,
  90. use: [
  91. {
  92. loader: 'cache-loader',
  93. options: {
  94. cacheDirectory: cacheDir
  95. }
  96. },
  97. 'style-loader',
  98. 'css-loader',
  99. 'postcss-loader',
  100. {
  101. loader: 'sass-loader',
  102. options: {
  103. implementation: require('sass'),
  104. sourceMap: false,
  105. sassOptions: {
  106. fiber: false
  107. }
  108. }
  109. },
  110. {
  111. loader: 'sass-resources-loader',
  112. options: {
  113. resources: path.join(process.cwd(), '/client/scss/global.scss')
  114. }
  115. }
  116. ]
  117. },
  118. {
  119. test: /\.vue$/,
  120. loader: 'vue-loader'
  121. },
  122. {
  123. test: /\.pug$/,
  124. exclude: [
  125. path.join(process.cwd(), 'dev')
  126. ],
  127. loader: 'pug-plain-loader'
  128. },
  129. {
  130. test: /\.(png|jpg|gif)$/,
  131. use: [
  132. {
  133. loader: 'url-loader',
  134. options: {
  135. limit: 8192
  136. }
  137. }
  138. ]
  139. },
  140. {
  141. test: /\.svg$/,
  142. exclude: [
  143. path.join(process.cwd(), 'node_modules/grapesjs')
  144. ],
  145. use: [
  146. {
  147. loader: 'file-loader',
  148. options: {
  149. name: '[name].[ext]',
  150. outputPath: 'svg/'
  151. }
  152. }
  153. ]
  154. },
  155. {
  156. test: /\.(graphql|gql)$/,
  157. exclude: /node_modules/,
  158. use: [
  159. { loader: 'graphql-persisted-document-loader' },
  160. { loader: 'graphql-tag/loader' }
  161. ]
  162. },
  163. {
  164. test: /\.(woff2|woff|ttf|eot)(\?v=\d+\.\d+\.\d+)?$/,
  165. use: [{
  166. loader: 'file-loader',
  167. options: {
  168. name: '[name].[ext]',
  169. outputPath: 'fonts/'
  170. }
  171. }]
  172. },
  173. {
  174. loader: 'webpack-modernizr-loader',
  175. test: /\.modernizrrc\.js$/
  176. }
  177. ]
  178. },
  179. plugins: [
  180. new VueLoaderPlugin(),
  181. new VuetifyLoaderPlugin(),
  182. new MomentTimezoneDataPlugin({
  183. startYear: 2017,
  184. endYear: (new Date().getFullYear()) + 5
  185. }),
  186. new CopyWebpackPlugin({
  187. patterns: [
  188. { from: 'client/static' },
  189. { from: './node_modules/prismjs/components', to: 'js/prism' }
  190. ]
  191. }),
  192. new HtmlWebpackPlugin({
  193. template: 'dev/templates/base.pug',
  194. filename: '../server/views/base.pug',
  195. hash: false,
  196. inject: false
  197. }),
  198. new HtmlWebpackPugPlugin(),
  199. new WebpackBarPlugin({
  200. name: 'Client Assets'
  201. }),
  202. new webpack.DefinePlugin({
  203. 'process.env.NODE_ENV': JSON.stringify('development'),
  204. 'process.env.CURRENT_THEME': JSON.stringify(_.defaultTo(yargs.theme, 'default'))
  205. }),
  206. new WriteFilePlugin(),
  207. new webpack.HotModuleReplacementPlugin(),
  208. new webpack.WatchIgnorePlugin([
  209. /node_modules/
  210. ])
  211. ],
  212. optimization: {
  213. namedModules: true,
  214. namedChunks: true,
  215. splitChunks: {
  216. cacheGroups: {
  217. default: {
  218. minChunks: 2,
  219. priority: -20,
  220. reuseExistingChunk: true
  221. },
  222. vendor: {
  223. test: /[\\/]node_modules[\\/]/,
  224. minChunks: 2,
  225. priority: -10
  226. }
  227. }
  228. },
  229. runtimeChunk: 'single'
  230. },
  231. resolve: {
  232. mainFields: ['browser', 'main', 'module'],
  233. symlinks: true,
  234. alias: {
  235. '@': path.join(process.cwd(), 'client'),
  236. 'vue$': 'vue/dist/vue.esm.js',
  237. 'gql': path.join(process.cwd(), 'client/graph'),
  238. // Duplicates fixes:
  239. 'apollo-link': path.join(process.cwd(), 'node_modules/apollo-link'),
  240. 'apollo-utilities': path.join(process.cwd(), 'node_modules/apollo-utilities'),
  241. 'uc.micro': path.join(process.cwd(), 'node_modules/uc.micro'),
  242. 'modernizr$': path.resolve(process.cwd(), 'client/.modernizrrc.js')
  243. },
  244. extensions: [
  245. '.js',
  246. '.json',
  247. '.vue'
  248. ],
  249. modules: [
  250. 'node_modules'
  251. ]
  252. },
  253. node: {
  254. fs: 'empty'
  255. },
  256. stats: {
  257. children: false,
  258. entrypoints: false
  259. },
  260. target: 'web',
  261. watch: true
  262. }