You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

webpack_pro.config.js 7.3 kB

3 years ago
3 years ago
3 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281
  1. const cssnano = require('cssnano');
  2. const fastGlob = require('fast-glob');
  3. const FixStyleOnlyEntriesPlugin = require('webpack-fix-style-only-entries');
  4. const MiniCssExtractPlugin = require('mini-css-extract-plugin');
  5. const MonacoWebpackPlugin = require('monaco-editor-webpack-plugin');
  6. const OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin');
  7. const PostCSSPresetEnv = require('postcss-preset-env');
  8. const PostCSSSafeParser = require('postcss-safe-parser');
  9. const SpriteLoaderPlugin = require('svg-sprite-loader/plugin');
  10. const TerserPlugin = require('terser-webpack-plugin');
  11. const VueLoaderPlugin = require('vue-loader/lib/plugin');
  12. const {statSync} = require('fs');
  13. const {resolve, parse} = require('path');
  14. //const {SourceMapDevToolPlugin} = require('webpack');
  15. const glob = (pattern) => fastGlob.sync(pattern, {cwd: __dirname, absolute: true});
  16. const themes = {};
  17. for (const path of glob('web_src/less/themes/*.less')) {
  18. themes[parse(path).name] = [path];
  19. }
  20. const standalone = {};
  21. const stadalonePaths = [
  22. ...glob('web_src/js/standalone/*.js'),
  23. ...glob('web_src/less/standalone/*.less'),
  24. ];
  25. for (const path of stadalonePaths) {
  26. standalone[parse(path).name] = [path];
  27. }
  28. const isProduction = process.env.NODE_ENV !== 'development';
  29. module.exports = {
  30. mode: isProduction ? 'production' : 'development',
  31. entry: {
  32. index: [
  33. resolve(__dirname, 'web_src/js/index.js'),
  34. resolve(__dirname, 'web_src/less/index.less'),
  35. ],
  36. jquery: [
  37. resolve(__dirname, 'web_src/js/jquery.js'),
  38. ],
  39. icons: glob('node_modules/@primer/octicons/build/svg/**/*.svg'),
  40. ...standalone,
  41. ...themes,
  42. },
  43. devtool: false,
  44. output: {
  45. path: resolve(__dirname, 'public'),
  46. filename: 'js/[name].js',
  47. chunkFilename: 'js/[name].js',
  48. },
  49. node:{
  50. fs: 'empty'
  51. },
  52. optimization: {
  53. minimize: isProduction,
  54. minimizer: [
  55. new TerserPlugin({
  56. sourceMap: true,
  57. extractComments: false,
  58. terserOptions: {
  59. keep_fnames: /^(HTML|SVG)/, // https://github.com/fgnass/domino/issues/144
  60. output: {
  61. comments: false,
  62. },
  63. },
  64. }),
  65. new OptimizeCSSAssetsPlugin({
  66. cssProcessor: cssnano,
  67. cssProcessorOptions: {
  68. parser: PostCSSSafeParser,
  69. },
  70. cssProcessorPluginOptions: {
  71. preset: [
  72. 'default',
  73. {
  74. discardComments: {
  75. removeAll: true,
  76. },
  77. },
  78. ],
  79. },
  80. }),
  81. ],
  82. splitChunks: {
  83. chunks: 'async',
  84. name: (_, chunks) => chunks.map((item) => item.name).join('-'),
  85. cacheGroups: {
  86. // this bundles all monaco's languages into one file instead of emitting 1-65.js files
  87. monaco: {
  88. test: /monaco-editor/,
  89. name: 'monaco',
  90. chunks: 'async'
  91. }
  92. }
  93. }
  94. },
  95. module: {
  96. rules: [
  97. {
  98. test: /\.vue$/,
  99. exclude: /node_modules/,
  100. loader: 'vue-loader',
  101. },
  102. {
  103. test: require.resolve('jquery-datetimepicker'),
  104. use: 'imports-loader?define=>false,exports=>false',
  105. },
  106. {
  107. test: /\.worker\.js$/,
  108. exclude: /monaco/,
  109. use: [
  110. {
  111. loader: 'worker-loader',
  112. options: {
  113. name: '[name].js',
  114. inline: true,
  115. fallback: false,
  116. },
  117. },
  118. ],
  119. },
  120. {
  121. test: /\.ts$/,
  122. use: [
  123. {
  124. loader: "ts-loader",
  125. }
  126. ],
  127. exclude: /node_modules/
  128. },
  129. {
  130. test: /\.js$/,
  131. exclude: /node_modules/,
  132. use: [
  133. {
  134. loader: 'babel-loader',
  135. options: {
  136. cacheDirectory: true,
  137. cacheCompression: false,
  138. cacheIdentifier: [
  139. resolve(__dirname, 'package.json'),
  140. resolve(__dirname, 'package-lock.json'),
  141. resolve(__dirname, 'webpack.config.js'),
  142. ].map((path) => statSync(path).mtime.getTime()).join(':'),
  143. sourceMaps: true,
  144. presets: [
  145. [
  146. '@babel/preset-env',
  147. {
  148. useBuiltIns: 'usage',
  149. corejs: 3,
  150. },
  151. ],
  152. ],
  153. plugins: [
  154. [
  155. '@babel/plugin-transform-runtime',
  156. {
  157. regenerator: true,
  158. }
  159. ],
  160. '@babel/plugin-proposal-object-rest-spread',
  161. ],
  162. },
  163. },
  164. ],
  165. },
  166. {
  167. test: /\.(less|css)$/i,
  168. use: [
  169. {
  170. loader: MiniCssExtractPlugin.loader,
  171. },
  172. {
  173. loader: 'css-loader',
  174. options: {
  175. importLoaders: 2,
  176. url: (_url, resourcePath) => {
  177. // only resolve URLs for dependencies
  178. return resourcePath.includes('node_modules');
  179. },
  180. }
  181. },
  182. {
  183. loader: 'postcss-loader',
  184. options: {
  185. plugins: () => [
  186. PostCSSPresetEnv(),
  187. ],
  188. },
  189. },
  190. {
  191. loader: 'less-loader',
  192. },
  193. ],
  194. },
  195. {
  196. test: /\.svg$/,
  197. use: [
  198. {
  199. loader: 'svg-sprite-loader',
  200. options: {
  201. extract: true,
  202. spriteFilename: 'img/svg/icons.svg',
  203. symbolId: (path) => {
  204. const {name} = parse(path);
  205. if (/@primer[/\\]octicons/.test(path)) {
  206. return `octicon-${name}`;
  207. }
  208. return name;
  209. },
  210. },
  211. },
  212. {
  213. loader: 'svgo-loader',
  214. },
  215. ],
  216. },
  217. {
  218. test: /\.(ttf|woff2?)$/,
  219. use: [
  220. {
  221. loader: 'file-loader',
  222. options: {
  223. name: '[name].[ext]',
  224. outputPath: 'fonts/',
  225. publicPath: (url) => `../fonts/${url}`, // seems required for monaco's font
  226. },
  227. },
  228. ],
  229. },
  230. ],
  231. },
  232. plugins: [
  233. new VueLoaderPlugin(),
  234. // avoid generating useless js output files for css- and svg-only chunks
  235. new FixStyleOnlyEntriesPlugin({
  236. extensions: ['less', 'scss', 'css', 'svg'],
  237. silent: true,
  238. }),
  239. new MiniCssExtractPlugin({
  240. filename: 'css/[name].css',
  241. chunkFilename: 'css/[name].css',
  242. }),
  243. //new SourceMapDevToolPlugin({
  244. //filename: 'js/[name].js.map',
  245. //include: [
  246. //'js/index.js',
  247. //],
  248. //}),
  249. new SpriteLoaderPlugin({
  250. plainSprite: true,
  251. }),
  252. new MonacoWebpackPlugin({
  253. filename: 'js/monaco-[name].worker.js',
  254. })
  255. ],
  256. performance: {
  257. hints: false,
  258. maxEntrypointSize: Infinity,
  259. maxAssetSize: Infinity,
  260. },
  261. resolve: {
  262. symlinks: false,
  263. alias: {
  264. vue$: 'vue/dist/vue.esm.js', // needed because vue's default export is the runtime only
  265. },
  266. extensions: ['.tsx', '.ts', '.js']
  267. },
  268. watchOptions: {
  269. ignored: [
  270. 'node_modules/**',
  271. ],
  272. },
  273. stats: {
  274. children: false,
  275. },
  276. };