You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

251 lines
5.8 KiB

  1. const path = require('path')
  2. const fs = require('fs-extra')
  3. const webpack = require('webpack')
  4. const CopyWebpackPlugin = require('copy-webpack-plugin')
  5. const ExtractTextPlugin = require('extract-text-webpack-plugin')
  6. const NameAllModulesPlugin = require('name-all-modules-plugin')
  7. const LodashModuleReplacementPlugin = require('lodash-webpack-plugin')
  8. const babelConfig = fs.readJsonSync(path.join(process.cwd(), '.babelrc'))
  9. const postCSSConfig = {
  10. config: {
  11. path: path.join(process.cwd(), 'dev/config/postcss.config.js')
  12. }
  13. }
  14. const cacheDir = '.webpack-cache/cache'
  15. const babelDir = path.join(process.cwd(), '.webpack-cache/babel')
  16. process.noDeprecation = true
  17. module.exports = {
  18. entry: {
  19. client: './client/index.js'
  20. },
  21. output: {
  22. path: path.join(process.cwd(), 'assets'),
  23. filename: 'js/[name].js',
  24. chunkFilename: 'js/[name].chunk.js'
  25. },
  26. module: {
  27. rules: [
  28. {
  29. test: /\.js$/,
  30. exclude: /node_modules/,
  31. use: [
  32. {
  33. loader: 'cache-loader',
  34. options: {
  35. cacheDirectory: cacheDir
  36. }
  37. },
  38. {
  39. loader: 'babel-loader',
  40. options: {
  41. ...babelConfig,
  42. cacheDirectory: babelDir
  43. }
  44. }
  45. ]
  46. },
  47. {
  48. test: /\.css$/,
  49. use: [
  50. {
  51. loader: 'style-loader'
  52. },
  53. {
  54. loader: 'css-loader'
  55. },
  56. {
  57. loader: 'postcss-loader',
  58. options: postCSSConfig
  59. }
  60. ]
  61. },
  62. {
  63. test: /\.scss$/,
  64. use: ExtractTextPlugin.extract({
  65. fallback: 'style-loader',
  66. use: [
  67. {
  68. loader: 'cache-loader',
  69. options: {
  70. cacheDirectory: cacheDir
  71. }
  72. },
  73. {
  74. loader: 'css-loader'
  75. },
  76. {
  77. loader: 'postcss-loader',
  78. options: postCSSConfig
  79. },
  80. {
  81. loader: 'sass-loader',
  82. options: {
  83. sourceMap: false
  84. }
  85. }
  86. ]
  87. })
  88. },
  89. {
  90. test: /\.styl$/,
  91. use: ExtractTextPlugin.extract({
  92. fallback: 'style-loader',
  93. use: [
  94. {
  95. loader: 'cache-loader',
  96. options: {
  97. cacheDirectory: cacheDir
  98. }
  99. },
  100. {
  101. loader: 'css-loader'
  102. },
  103. {
  104. loader: 'stylus-loader'
  105. }
  106. ]
  107. })
  108. },
  109. {
  110. test: /\.vue$/,
  111. loader: 'vue-loader',
  112. options: {
  113. extractCSS: ExtractTextPlugin,
  114. postcss: postCSSConfig,
  115. loaders: {
  116. css: [
  117. {
  118. loader: 'vue-style-loader'
  119. },
  120. {
  121. loader: 'css-loader'
  122. }
  123. ],
  124. scss: [
  125. {
  126. loader: 'vue-style-loader'
  127. },
  128. {
  129. loader: 'css-loader'
  130. },
  131. {
  132. loader: 'sass-loader',
  133. options: {
  134. sourceMap: false
  135. }
  136. },
  137. {
  138. loader: 'sass-resources-loader',
  139. options: {
  140. resources: path.join(process.cwd(), '/client/scss/global.scss')
  141. }
  142. }
  143. ],
  144. js: [
  145. {
  146. loader: 'cache-loader',
  147. options: {
  148. cacheDirectory: cacheDir
  149. }
  150. },
  151. {
  152. loader: 'babel-loader',
  153. options: {
  154. babelrc: path.join(process.cwd(), '.babelrc'),
  155. cacheDirectory: babelDir
  156. }
  157. }
  158. ]
  159. }
  160. }
  161. },
  162. {
  163. test: /\.(png|jpg|gif)$/,
  164. use: [
  165. {
  166. loader: 'url-loader',
  167. options: {
  168. limit: 8192
  169. }
  170. }
  171. ]
  172. },
  173. {
  174. test: /\.svg$/,
  175. exclude: [
  176. path.join(process.cwd(), 'client/svg')
  177. ],
  178. use: [
  179. {
  180. loader: 'file-loader',
  181. options: {
  182. name: '[name].[ext]',
  183. outputPath: 'svg/'
  184. }
  185. }
  186. ]
  187. },
  188. {
  189. test: /\.svg$/,
  190. include: [
  191. path.join(process.cwd(), 'client/svg')
  192. ],
  193. use: [
  194. {
  195. loader: 'raw-loader'
  196. }
  197. ]
  198. }
  199. ]
  200. },
  201. plugins: [
  202. new webpack.BannerPlugin('Wiki.js - wiki.js.org - Licensed under AGPL'),
  203. new CopyWebpackPlugin([
  204. { from: 'client/static' }
  205. ], {
  206. }),
  207. new LodashModuleReplacementPlugin(),
  208. new webpack.NamedModulesPlugin(),
  209. new webpack.NamedChunksPlugin((chunk) => {
  210. if (chunk.name) {
  211. return chunk.name
  212. }
  213. return chunk.modules.map(m => path.relative(m.context, m.request)).join('_')
  214. }),
  215. new webpack.optimize.CommonsChunkPlugin({
  216. name: 'vendor',
  217. minChunks(module) {
  218. return module.context && module.context.includes('node_modules')
  219. }
  220. }),
  221. new webpack.optimize.CommonsChunkPlugin({
  222. name: 'runtime',
  223. minChunks: Infinity
  224. }),
  225. new NameAllModulesPlugin()
  226. ],
  227. resolve: {
  228. symlinks: true,
  229. alias: {
  230. '@': path.join(process.cwd(), 'client'),
  231. 'vue$': 'vue/dist/vue.esm.js',
  232. // Duplicates fixes:
  233. 'apollo-link': path.join(process.cwd(), 'node_modules/apollo-link'),
  234. 'apollo-utilities': path.join(process.cwd(), 'node_modules/apollo-utilities')
  235. },
  236. extensions: [
  237. '.js',
  238. '.json',
  239. '.vue'
  240. ],
  241. modules: [
  242. 'node_modules'
  243. ]
  244. },
  245. target: 'web'
  246. }