webpack.config.js 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287
  1. /**
  2. * @file Manages the root configuration settings for webpack.
  3. * @module webpack/root/configuration
  4. * @see {@link https://webpack.js.org/} for further information.
  5. */
  6. const path = require('path');
  7. const childProcess = require('child_process');
  8. const webpack = require('webpack');
  9. const merge = require('webpack-merge');
  10. const TerserPlugin = require('terser-webpack-plugin');
  11. const eslintFriendlyFormatter = require('eslint-friendly-formatter');
  12. const {BundleAnalyzerPlugin} = require('webpack-bundle-analyzer');
  13. const getGlobal = function() {
  14. 'use strict';
  15. if (typeof self !== 'undefined') {
  16. return self;
  17. }
  18. if (typeof window !== 'undefined') {
  19. return window;
  20. }
  21. if (typeof global !== 'undefined') {
  22. return global;
  23. }
  24. return Function('return this')();
  25. };
  26. const filename = 'v-click-outside-x';
  27. const library = 'vClickOutside';
  28. const dist = path.resolve(__dirname, 'dist');
  29. /**
  30. * The NODE_ENV environment variable.
  31. * @type {!Object}
  32. */
  33. const {NODE_ENV} = process.env;
  34. /**
  35. * The production string.
  36. * @type {string}
  37. */
  38. const PRODUCTION = 'production';
  39. /**
  40. * The development string.
  41. * @type {string}
  42. */
  43. const DEVELOPMENT = 'development';
  44. /**
  45. * The default include paths.
  46. * @type {string}
  47. */
  48. const DEFAULT_INCLUDE = [
  49. path.resolve(__dirname, 'src'),
  50. path.resolve(__dirname, '__tests__'),
  51. ];
  52. /**
  53. * Allows you to pass in as many environment variables as you like using --env.
  54. * See {@link http://webpack.js.org/guides/environment-variables}.
  55. *
  56. * @param {!Object} [env={}] - The env object.
  57. * @returns {undefined} Default.
  58. */
  59. module.exports = function generateConfig(env) {
  60. /**
  61. * The JSON content of `package.json`
  62. * @type {!Object}
  63. */
  64. const PACKAGE = require('./package.json');
  65. /**
  66. * The reference created bu git describe --dirty`
  67. * @type {string}
  68. * @see {@link https://git-scm.com/docs/git-describe}
  69. */
  70. const DESCRIBE = childProcess
  71. .spawnSync('git', ['describe', '--dirty'])
  72. .output[1].toString()
  73. .trim();
  74. /**
  75. * The date as of now.
  76. * @type {string}
  77. */
  78. const NOW = new Date().toISOString();
  79. const base = {
  80. /**
  81. * This option controls if and how source maps are generated.
  82. *
  83. * nosources-source-map - A SourceMap is created without the sourcesContent in it.
  84. * It can be used to map stack traces on the client without exposing all of the
  85. * source code. You can deploy the Source Map file to the web-server.
  86. *
  87. * eval-source-map - Each module is executed with eval() and a SourceMap is added as
  88. * a DataUrl to the eval(). Initially it is slow, but it provides fast rebuild speed
  89. * and yields real files. Line numbers are correctly mapped since it gets mapped to
  90. * the original code. It yields the best quality SourceMaps for development.
  91. *
  92. * source-map - A full SourceMap is emitted as a separate file. It adds a reference
  93. * comment to the bundle so development tools know where to find it.
  94. *
  95. * @type {string}
  96. * @see {@link https://webpack.js.org/configuration/devtool/}
  97. */
  98. devtool: 'source-map',
  99. /**
  100. * Define the entry points for the application.
  101. * @type {array.<string>}
  102. * @see {@link https://webpack.js.org/concepts/entry-points/}
  103. */
  104. entry: './src/index.js',
  105. mode: NODE_ENV === PRODUCTION ? PRODUCTION : DEVELOPMENT,
  106. /**
  107. * In modular programming, developers break programs up into discrete chunks of functionality
  108. * called a module. Each module has a smaller surface area than a full program, making verification,
  109. * debugging, and testing trivial. Well-written modules provide solid abstractions and encapsulation
  110. * boundaries, so that each module has a coherent design and a clear purpose within the overall
  111. * application.
  112. *
  113. * webpack supports modules written in a variety of languages and preprocessors, via loaders.
  114. * Loaders describe to webpack how to process non-JavaScript modules and include these dependencies
  115. * into your bundles.
  116. *
  117. * @type {array.<!Object>}
  118. * @see {@link https://webpack.js.org/configuration/module/#module-rules}
  119. */
  120. module: {
  121. rules: [
  122. /**
  123. * eslint-loader options.
  124. * @type {!Object}
  125. * @see {@link https://github.com/MoOx/eslint-loader}
  126. */
  127. {
  128. enforce: 'pre',
  129. include: DEFAULT_INCLUDE,
  130. loader: 'eslint-loader',
  131. options: {
  132. emitError: true,
  133. emitWarning: false,
  134. failOnError: true,
  135. failOnWarning: false,
  136. formatter: eslintFriendlyFormatter,
  137. quiet: true,
  138. },
  139. test: /\.(js|json)$/,
  140. },
  141. /**
  142. * This package allows transpiling JavaScript files using Babel and webpack.
  143. *
  144. * @see {@link https://webpack.js.org/loaders/babel-loader/}
  145. */
  146. {
  147. include: DEFAULT_INCLUDE,
  148. loader: 'babel-loader',
  149. test: /\.js$/,
  150. },
  151. ],
  152. },
  153. // prevent webpack from injecting mocks to Node native modules
  154. // that does not make sense for the client
  155. node: {
  156. child_process: 'empty',
  157. dgram: 'empty',
  158. fs: 'empty',
  159. net: 'empty',
  160. // prevent webpack from injecting useless setImmediate polyfill.
  161. setImmediate: false,
  162. tls: 'empty',
  163. },
  164. /**
  165. * Configuring the output configuration options tells webpack how to write the compiled
  166. * files to disk.
  167. * @type {!Object}
  168. * @see {@link https://webpack.js.org/configuration/output/}
  169. */
  170. output: {
  171. // https://github.com/webpack/webpack/issues/6525
  172. globalObject: `(${getGlobal.toString()}())`,
  173. library,
  174. libraryTarget: 'umd',
  175. path: dist,
  176. },
  177. /**
  178. * Plugins are the backbone of webpack. Webpack itself is built on the same plugin system
  179. * that you use in your webpack configuration!
  180. *
  181. * A webpack plugin is a JavaScript object that has an apply property. This apply property
  182. * is called by the webpack compiler, giving access to the entire compilation lifecycle.
  183. *
  184. */
  185. plugins: [
  186. /**
  187. * Adds a banner to the top of each generated chunk.
  188. * @type {!Object}
  189. * @see {@link https://webpack.js.org/plugins/banner-plugin/}
  190. */
  191. new webpack.BannerPlugin({
  192. banner: `/*!\n${JSON.stringify(
  193. {
  194. copywrite: `${PACKAGE.copyright}`,
  195. date: `${NOW}`,
  196. describe: `${DESCRIBE}`,
  197. description: `${PACKAGE.description}`,
  198. file: '[file]',
  199. hash: '[hash]',
  200. license: `${PACKAGE.license}`,
  201. version: `${PACKAGE.version}`,
  202. },
  203. null,
  204. 2,
  205. )}\n*/`,
  206. raw: true,
  207. }),
  208. ],
  209. /**
  210. * These options change how modules are resolved.
  211. * @type {!Object}
  212. * @see {@link https://webpack.js.org/configuration/resolve/}
  213. */
  214. resolve: {
  215. /**
  216. * Create aliases to import or require certain modules more easily.
  217. * @type {!Object}
  218. * @see {@link https://webpack.js.org/configuration/resolve/#resolve-alias}
  219. */
  220. alias: {
  221. RootDir: path.resolve(__dirname, '.'),
  222. dist: path.resolve(__dirname, './dist'),
  223. src: path.resolve(__dirname, './src'),
  224. },
  225. extensions: ['.js', '.json'],
  226. },
  227. };
  228. const browser = merge(base, {
  229. optimization: {
  230. minimize: false,
  231. },
  232. output: {
  233. filename: `${filename}.js`,
  234. },
  235. });
  236. const minified = merge(browser, {
  237. output: {
  238. filename: `${filename}.min.js`,
  239. },
  240. /**
  241. * Webpack plugin and CLI utility that represents bundle content as convenient
  242. * interactive zoomable treemap.
  243. *
  244. * @see {@link https://github.com/webpack-contrib/webpack-bundle-analyzer}
  245. */
  246. plugins: [
  247. new TerserPlugin({
  248. parallel: true,
  249. sourceMap: true,
  250. terserOptions: {
  251. ecma: 5,
  252. },
  253. }),
  254. ...(env && env.report ? [new BundleAnalyzerPlugin()] : []),
  255. ],
  256. });
  257. return [browser, minified];
  258. };