webpack.config.dev.js 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198
  1. /* eslint-disable import/no-named-as-default-member */
  2. const path = require('path');
  3. const _ = require('lodash');
  4. const webpack = require('webpack');
  5. const HtmlWebpackPlugin = require('html-webpack-plugin');
  6. const ModuleScopePlugin = require('react-dev-utils/ModuleScopePlugin');
  7. // const InterpolateHtmlPlugin = require('react-dev-utils/InterpolateHtmlPlugin');
  8. const CaseSensitivePathsPlugin = require('case-sensitive-paths-webpack-plugin');
  9. const ProgressBarPlugin = require('progress-bar-webpack-plugin');
  10. const WebpackPluginFrTheme = require('webpack-plugin-fr-theme');
  11. const AddAssetHtmlPlugin = require('add-asset-html-webpack-plugin');
  12. // const HardSourceWebpackPlugin = require('hard-source-webpack-plugin');
  13. const CircularDependencyPlugin = require('circular-dependency-plugin');
  14. const HardSourceWebpackPlugin = require('hard-source-webpack-plugin');
  15. const HappyPack = require('happypack');
  16. const os = require('os');
  17. const getClientEnvironment = require('./env');
  18. const paths = require('./paths');
  19. const loaders = require('./loader.dev');
  20. // const Jarvis = require('webpack-jarvis');
  21. const publicUrl = '';
  22. const contextPath = process.env._SETTING_CONTEXT_PATH;
  23. const env = getClientEnvironment(publicUrl);
  24. // 根据系统的内核数量 指定线程池个数 也可以其他数量
  25. /*eslint-disable babel/new-cap */
  26. const happyThreadPool = HappyPack.ThreadPool({ size: os.cpus().length });
  27. module.exports = {
  28. mode: 'development',
  29. cache: true,
  30. entry: {
  31. app: [
  32. // require.resolve('babel-polyfill'),
  33. 'webpack-dev-server/client?http://0.0.0.0:3000',
  34. 'webpack/hot/only-dev-server',
  35. paths.appIndexJs,
  36. ],
  37. vendor: [
  38. 'react',
  39. 'prop-types',
  40. 'react-dom',
  41. 'react-router',
  42. 'react-router-dom',
  43. 'axios',
  44. 'lodash',
  45. 'moment',
  46. 'normalizr',
  47. ],
  48. },
  49. // devtool: 'cheap-module-eval-source-map',
  50. devtool: 'cheap-module-source-map',
  51. // devtool: 'eval',
  52. output: {
  53. path: paths.appBuild,
  54. pathinfo: true,
  55. publicPath: '',
  56. filename: 'static/js/[name].[hash:7].js',
  57. sourceMapFilename: 'static/js/[name].[hash:7].map',
  58. chunkFilename: 'static/js/[name].[chunkhash:7].chunk.js',
  59. },
  60. resolve: {
  61. modules: [paths.appSrc, paths.appNodeModules],
  62. extensions: ['.jsx', '.js', '.scss', '.css', '.json'],
  63. alias: {
  64. '@': paths.appSrc,
  65. },
  66. plugins: [
  67. // 阻止从src和node_modules目录之外导入模块
  68. new ModuleScopePlugin(paths.appSrc, [paths.appPackageJson]),
  69. ],
  70. },
  71. target: 'web',
  72. module: {
  73. rules: [
  74. loaders.eslintLoader,
  75. {
  76. oneOf: [
  77. {
  78. test: /\.(js|jsx)$/,
  79. use: `happypack/loader?id=babel`,
  80. exclude: /node_modules/,
  81. include: paths.appSrc,
  82. },
  83. loaders.cssLoaderRule,
  84. loaders.scssLoaderRule,
  85. {
  86. test: /\.(less)$/,
  87. use: `happypack/loader?id=less`,
  88. },
  89. loaders.svgSpriteLoader,
  90. loaders.fontWoffLoader,
  91. loaders.fontTtfLoader,
  92. loaders.mediaLoader,
  93. loaders.otherLoader,
  94. ],
  95. },
  96. ],
  97. },
  98. optimization: {
  99. namedModules: true,
  100. runtimeChunk: {
  101. name: 'manifest',
  102. },
  103. splitChunks: {
  104. chunks: 'async',
  105. minSize: 30000,
  106. minChunks: 1,
  107. maxAsyncRequests: 5,
  108. maxInitialRequests: 3,
  109. name: false,
  110. cacheGroups: {
  111. vendor: {
  112. name: 'vendor',
  113. chunks: 'initial',
  114. priority: -10,
  115. reuseExistingChunk: false,
  116. test: /node_modules\/(.*)\.js/,
  117. },
  118. },
  119. },
  120. },
  121. performance: {
  122. // 开启性能提示
  123. hints: false,
  124. },
  125. plugins: [
  126. new WebpackPluginFrTheme(),
  127. new ProgressBarPlugin({
  128. format: 'Build [:bar] :percent (:elapsed seconds)',
  129. clear: false,
  130. }),
  131. // new HardSourceWebpackPlugin(),
  132. new webpack.NamedModulesPlugin(),
  133. new webpack.optimize.ModuleConcatenationPlugin(),
  134. // 创建编译时配置的全局常量
  135. new webpack.DefinePlugin(env.stringified),
  136. // 强制执行所有必需模块的整个路径,以匹配确切的大小写
  137. new CaseSensitivePathsPlugin(),
  138. new CircularDependencyPlugin({
  139. exclude: /node_modules/,
  140. failOnError: true,
  141. allowAsyncCycles: false,
  142. cwd: process.cwd(),
  143. }),
  144. new HappyPack({
  145. id: 'babel',
  146. loaders: [loaders.jsLoader],
  147. threadPool: happyThreadPool,
  148. verbose: true,
  149. }),
  150. new HappyPack({
  151. id: 'less',
  152. loaders: ['style-loader', loaders.cssLoaderConfig, loaders.postCssLoaderConfig, loaders.lessLoaderConfig],
  153. threadPool: happyThreadPool,
  154. verbose: true,
  155. }),
  156. new webpack.DllReferencePlugin({
  157. manifest: require(path.join(paths.appDist, 'vendor.manifest.json')),
  158. sourceType: 'var',
  159. context: paths.appSrc,
  160. }),
  161. // new InterpolateHtmlPlugin(env.raw),
  162. new HtmlWebpackPlugin({
  163. hash: false, // 为所有注入的静态资源添加webpack每次编译产生的唯一hash值
  164. inject: true, // 向templateContent中注入所有静态资源,注入到body元素底部
  165. template: paths.appHtml,
  166. sourceMap: true,
  167. basePath: _.isEmpty(contextPath) ? '/' : `/${contextPath}/`,
  168. }),
  169. new AddAssetHtmlPlugin([
  170. {
  171. hash: true,
  172. filepath: require.resolve(path.join(paths.appDist, 'vendor.dll.js')),
  173. },
  174. ]),
  175. // new Jarvis({
  176. // port: 1337,
  177. // }),
  178. // 启用HRM
  179. new webpack.HotModuleReplacementPlugin(),
  180. /* eslint-disable no-useless-escape */
  181. // 上下文替换插件(ContextReplacementPlugin) 允许你覆盖查找规则,减少打包时的local资源
  182. new webpack.ContextReplacementPlugin(/moment[\/\\]locale$/, /en-gb|zh-cn/),
  183. // //模块提供中间缓存步骤
  184. new HardSourceWebpackPlugin(),
  185. new HardSourceWebpackPlugin.ExcludeModulePlugin([
  186. {
  187. // HardSource works with mini-css-extract-plugin but due to how
  188. // mini-css emits assets, assets are not emitted on repeated builds with
  189. // mini-css and hard-source together. Ignoring the mini-css loader
  190. // modules, but not the other css loader modules, excludes the modules
  191. // that mini-css needs rebuilt to output assets every time.
  192. test: /mini-css-extract-plugin[\\/]dist[\\/]loader/,
  193. },
  194. ]),
  195. ],
  196. };