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.

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