webpack.config.js 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151
  1. const webpack = require("webpack");
  2. const path = require("path");
  3. const CleanupPlugin = require("clean-webpack-plugin");
  4. const HtmlWebpackPlugin = require("html-webpack-plugin");
  5. const ExtractTextPlugin = require("extract-text-webpack-plugin");
  6. const autoprefixer = require("autoprefixer");
  7. const nodeEnv = process.env.NODE_ENV || "development";
  8. const plugins = [
  9. new webpack.optimize.CommonsChunkPlugin({
  10. name: "commons",
  11. filename: "[name]-[hash].js",
  12. chunks: ["vendor", "app"]
  13. }),
  14. new HtmlWebpackPlugin({
  15. hash: true,
  16. chunks: ["commons", "app"],
  17. template: "index.tpl.html",
  18. inject: "body",
  19. filename: "index.html"
  20. }),
  21. new webpack.optimize.OccurrenceOrderPlugin(),
  22. new webpack.HotModuleReplacementPlugin(),
  23. new webpack.NoEmitOnErrorsPlugin(),
  24. new webpack.DefinePlugin({
  25. "process.env": {
  26. NODE_ENV: JSON.stringify(nodeEnv),
  27. },
  28. }),
  29. new webpack.NamedModulesPlugin(),
  30. new CleanupPlugin(["dist"], {
  31. verbose: true,
  32. dry: false,
  33. watch: true,
  34. }),
  35. new webpack.LoaderOptionsPlugin({
  36. options: {
  37. postcss: [
  38. autoprefixer({
  39. browsers: [
  40. "last 3 version",
  41. "ie >= 10",
  42. ],
  43. }),
  44. ],
  45. context: path.join(__dirname, "./app"),
  46. },
  47. }),
  48. ];
  49. const rules = [
  50. {
  51. test: /\.(js|jsx)$/,
  52. exclude: /node_modules/,
  53. use: [
  54. "babel-loader",
  55. ],
  56. },
  57. {
  58. test: /\.(png|gif|jpg|svg)$/,
  59. include: path.join(__dirname, "./app/assets/images"),
  60. use: "url-loader?limit=20480&name=assets/[name]-[hash].[ext]",
  61. },
  62. ];
  63. if (nodeEnv === "production") {
  64. plugins.push(
  65. new webpack.LoaderOptionsPlugin({
  66. minimize: true,
  67. debug: false,
  68. }),
  69. new webpack.optimize.UglifyJsPlugin({
  70. compress: {
  71. warnings: false,
  72. screw_ie8: true,
  73. conditionals: true,
  74. unused: true,
  75. comparisons: true,
  76. sequences: true,
  77. dead_code: true,
  78. evaluate: true,
  79. if_return: true,
  80. join_vars: true,
  81. },
  82. output: {
  83. comments: false,
  84. },
  85. }),
  86. new ExtractTextPlugin("style-[hash].css")
  87. );
  88. rules.push({
  89. test: /\.scss$/,
  90. loader: ExtractTextPlugin.extract({
  91. fallback: "style-loader",
  92. use: "css-loader!postcss-loader!sass-loader",
  93. }),
  94. });
  95. } else {
  96. rules.push({
  97. test: /\.scss$/,
  98. exclude: /node_modules/,
  99. use: [
  100. "style-loader",
  101. // "css-loader?sourceMap",
  102. "css-loader",
  103. "postcss-loader",
  104. "sass-loader?sourceMap",
  105. ],
  106. });
  107. }
  108. module.exports = {
  109. devtool: nodeEnv === "production" ? "eval" : "source-map",
  110. context: path.join(__dirname, "./app"),
  111. entry: {
  112. app: "./js/index.js",
  113. vendor: [
  114. "babel-polyfill",
  115. "es6-promise",
  116. "immutable",
  117. "isomorphic-fetch",
  118. "react-dom",
  119. "react-redux",
  120. "react-router-dom",
  121. "react",
  122. "redux-thunk",
  123. "redux",
  124. ],
  125. },
  126. output: {
  127. path: path.join(__dirname, "./dist"),
  128. publicPath: "/",
  129. filename: "[name]-[hash].js",
  130. },
  131. module: {
  132. rules,
  133. },
  134. resolve: {
  135. extensions: [".webpack-loader.js", ".web-loader.js", ".loader.js", ".js", ".jsx"],
  136. modules: [
  137. path.resolve(__dirname, "node_modules"),
  138. path.resolve(__dirname, "./app/js"),
  139. path.resolve(__dirname, "./"),
  140. path.resolve(__dirname, "./app/styles"),
  141. ],
  142. },
  143. plugins,
  144. };