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.

285 lines
9.3 KiB

  1. 'use strict';
  2. const fs = require('fs');
  3. const glob = require('glob');
  4. const path = require('path');
  5. const webpack = require('webpack');
  6. const CleanPlugin = require('clean-webpack-plugin');
  7. const FileManagerPlugin = require('filemanager-webpack-plugin');
  8. const HtmlInlineSourcePlugin = require('html-webpack-inline-source-plugin');
  9. const HtmlPlugin = require('html-webpack-plugin');
  10. const ImageminPlugin = require('imagemin-webpack-plugin').default;
  11. const MiniCssExtractPlugin = require('mini-css-extract-plugin');
  12. // const SizePlugin = require('size-plugin');
  13. // const WebpackDeepScopeAnalysisPlugin = require('webpack-deep-scope-plugin').default;
  14. module.exports = function(env, argv) {
  15. env = env || {};
  16. env.production = Boolean(env.production);
  17. env.optimizeImages = env.production || Boolean(env.optimizeImages);
  18. env.copyClipboardyFallbacks = env.production || Boolean(env.copyClipboardyFallbacks);
  19. if (!env.optimizeImages && !fs.existsSync(path.resolve(__dirname, 'images/settings'))) {
  20. env.optimizeImages = true;
  21. }
  22. if (!env.copyClipboardyFallbacks && !fs.existsSync(path.resolve(__dirname, 'fallbacks'))) {
  23. env.copyClipboardyFallbacks = true;
  24. }
  25. return [getExtensionConfig(env), getUIConfig(env)];
  26. };
  27. function getExtensionConfig(env) {
  28. const clean = ['dist'];
  29. if (env.copyClipboardyFallbacks) {
  30. clean.push('fallbacks');
  31. }
  32. const plugins = [
  33. // https://github.com/GoogleChromeLabs/size-plugin/issues/12
  34. // new SizePlugin(),
  35. new CleanPlugin(clean, { verbose: false }),
  36. new webpack.IgnorePlugin(/^spawn-sync$/)
  37. ];
  38. if (env.copyClipboardyFallbacks) {
  39. plugins.push(
  40. // @ts-ignore
  41. new FileManagerPlugin({
  42. onEnd: [
  43. {
  44. copy: [
  45. {
  46. source: path.resolve(__dirname, 'node_modules/clipboardy/fallbacks'),
  47. destination: 'fallbacks/'
  48. }
  49. ]
  50. }
  51. ]
  52. })
  53. );
  54. }
  55. // if (env.production) {
  56. // plugins.push(new WebpackDeepScopeAnalysisPlugin());
  57. // }
  58. return {
  59. name: 'extension',
  60. entry: './src/extension.ts',
  61. mode: env.production ? 'production' : 'development',
  62. target: 'node',
  63. node: {
  64. __dirname: false
  65. },
  66. devtool: !env.production ? 'eval-source-map' : undefined,
  67. output: {
  68. libraryTarget: 'commonjs2',
  69. filename: 'extension.js',
  70. path: path.resolve(__dirname, 'dist'),
  71. devtoolModuleFilenameTemplate: 'file:///[absolute-resource-path]'
  72. },
  73. externals: {
  74. vscode: 'commonjs vscode'
  75. },
  76. module: {
  77. rules: [
  78. {
  79. test: /\.ts$/,
  80. enforce: 'pre',
  81. use: 'tslint-loader'
  82. },
  83. {
  84. test: /\.tsx?$/,
  85. use: 'ts-loader',
  86. exclude: /node_modules/
  87. }
  88. ]
  89. },
  90. resolve: {
  91. extensions: ['.ts', '.tsx', '.js', '.jsx']
  92. },
  93. plugins: plugins,
  94. stats: {
  95. all: false,
  96. assets: true,
  97. builtAt: true,
  98. env: true,
  99. errors: true,
  100. timings: true,
  101. warnings: true
  102. }
  103. };
  104. }
  105. function getUIConfig(env) {
  106. const clean = ['settings.html', 'welcome.html'];
  107. if (env.optimizeImages) {
  108. console.log('Optimizing images (src/ui/images/settings/*.png)...');
  109. clean.push('images/settings');
  110. }
  111. const plugins = [
  112. // https://github.com/GoogleChromeLabs/size-plugin/issues/12
  113. // new SizePlugin(),
  114. new CleanPlugin(clean, { verbose: false }),
  115. new MiniCssExtractPlugin({
  116. filename: '[name].css'
  117. }),
  118. new HtmlPlugin({
  119. excludeAssets: [/.*\.main\.js/],
  120. excludeChunks: ['welcome'],
  121. template: 'settings/index.html',
  122. filename: path.resolve(__dirname, 'settings.html'),
  123. inject: true,
  124. inlineSource: env.production ? '.(js|css)$' : undefined,
  125. // inlineSource: '.(js|css)$',
  126. minify: env.production
  127. ? {
  128. removeComments: true,
  129. collapseWhitespace: true,
  130. removeRedundantAttributes: true,
  131. useShortDoctype: true,
  132. removeEmptyAttributes: true,
  133. removeStyleLinkTypeAttributes: true,
  134. keepClosingSlash: true
  135. }
  136. : false
  137. }),
  138. new HtmlPlugin({
  139. excludeAssets: [/.*\.main\.js/],
  140. excludeChunks: ['settings'],
  141. template: 'welcome/index.html',
  142. filename: path.resolve(__dirname, 'welcome.html'),
  143. inject: true,
  144. inlineSource: env.production ? '.(js|css)$' : undefined,
  145. // inlineSource: '.(js|css)$',
  146. minify: env.production
  147. ? {
  148. removeComments: true,
  149. collapseWhitespace: true,
  150. removeRedundantAttributes: true,
  151. useShortDoctype: true,
  152. removeEmptyAttributes: true,
  153. removeStyleLinkTypeAttributes: true,
  154. keepClosingSlash: true
  155. }
  156. : false
  157. }),
  158. new HtmlInlineSourcePlugin(),
  159. new ImageminPlugin({
  160. disable: !env.optimizeImages,
  161. externalImages: {
  162. context: path.resolve(__dirname, 'src/ui/images'),
  163. sources: glob.sync('src/ui/images/settings/*.png'),
  164. destination: path.resolve(__dirname, 'images')
  165. },
  166. cacheFolder: path.resolve(__dirname, '.cache-images'),
  167. gifsicle: null,
  168. jpegtran: null,
  169. optipng: null,
  170. pngquant: {
  171. quality: '85-100',
  172. speed: env.production ? 1 : 10
  173. },
  174. svgo: null
  175. })
  176. ];
  177. // if (env.production) {
  178. // plugins.push(new WebpackDeepScopeAnalysisPlugin());
  179. // }
  180. return {
  181. name: 'ui',
  182. context: path.resolve(__dirname, 'src/ui'),
  183. // This is ugly having main.scss on both bundles, but if it is added separately it will generate a js bundle :(
  184. entry: {
  185. settings: ['./settings/index.ts', './scss/main.scss'],
  186. welcome: ['./welcome/index.ts', './scss/main.scss']
  187. // main: ['./scss/main.scss']
  188. },
  189. mode: env.production ? 'production' : 'development',
  190. devtool: !env.production ? 'eval-source-map' : undefined,
  191. output: {
  192. filename: '[name].js',
  193. path: path.resolve(__dirname, 'dist/ui'),
  194. publicPath: '{{root}}/dist/ui/'
  195. },
  196. optimization: {
  197. splitChunks: {
  198. cacheGroups: {
  199. styles: {
  200. name: 'styles',
  201. test: /\.css$/,
  202. chunks: 'all',
  203. enforce: true
  204. }
  205. }
  206. }
  207. },
  208. module: {
  209. rules: [
  210. {
  211. test: /\.ts$/,
  212. enforce: 'pre',
  213. use: [
  214. {
  215. loader: 'tslint-loader',
  216. options: {
  217. tsConfigFile: 'ui.tsconfig.json'
  218. }
  219. }
  220. ]
  221. },
  222. {
  223. test: /\.tsx?$/,
  224. use: {
  225. loader: 'ts-loader',
  226. options: {
  227. configFile: 'ui.tsconfig.json'
  228. }
  229. },
  230. exclude: /node_modules/
  231. },
  232. {
  233. test: /\.scss$/,
  234. use: [
  235. {
  236. loader: MiniCssExtractPlugin.loader
  237. },
  238. {
  239. loader: 'css-loader',
  240. options: {
  241. minimize: env.production,
  242. sourceMap: !env.production,
  243. url: false
  244. }
  245. },
  246. {
  247. loader: 'sass-loader',
  248. options: {
  249. sourceMap: !env.production
  250. }
  251. }
  252. ],
  253. exclude: /node_modules/
  254. }
  255. ]
  256. },
  257. resolve: {
  258. extensions: ['.ts', '.tsx', '.js', '.jsx'],
  259. modules: [path.resolve(__dirname, 'src/ui'), 'node_modules']
  260. },
  261. plugins: plugins,
  262. stats: {
  263. all: false,
  264. assets: true,
  265. builtAt: true,
  266. env: true,
  267. errors: true,
  268. timings: true,
  269. warnings: true
  270. }
  271. };
  272. }