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.

309 lines
10 KiB

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