mirror of
				https://github.com/superseriousbusiness/gotosocial.git
				synced 2025-10-31 14:32:24 -05:00 
			
		
		
		
	[chore] Bundler restructure (#880)
* re-structure bundler, settings panel files * add more info logging * tidy up CSS syntax errors * split into lib/ files * livereloading server * fix factor function for production builds * remove testing console.log * default to production env, saves 300kb bundle size
This commit is contained in:
		
					parent
					
						
							
								56f53a2a6f
							
						
					
				
			
			
				commit
				
					
						5249294a16
					
				
			
		
					 40 changed files with 503 additions and 434 deletions
				
			
		
							
								
								
									
										200
									
								
								web/source/lib/bundler.js
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										200
									
								
								web/source/lib/bundler.js
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,200 @@ | |||
| /* | ||||
| 	GoToSocial | ||||
| 	Copyright (C) 2021-2022 GoToSocial Authors admin@gotosocial.org | ||||
| 
 | ||||
| 	This program is free software: you can redistribute it and/or modify | ||||
| 	it under the terms of the GNU Affero General Public License as published by | ||||
| 	the Free Software Foundation, either version 3 of the License, or | ||||
| 	(at your option) any later version. | ||||
| 
 | ||||
| 	This program is distributed in the hope that it will be useful, | ||||
| 	but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
| 	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
| 	GNU Affero General Public License for more details. | ||||
| 
 | ||||
| 	You should have received a copy of the GNU Affero General Public License | ||||
| 	along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | ||||
| */ | ||||
| 
 | ||||
| "use strict"; | ||||
| 
 | ||||
| const Promise = require("bluebird"); | ||||
| const browserify = require("browserify"); | ||||
| const babelify = require('babelify'); | ||||
| const chalk = require("chalk"); | ||||
| const fs = require("fs").promises; | ||||
| const { EventEmitter } = require("events"); | ||||
| const path = require("path"); | ||||
| const debugLib = require("debug"); | ||||
| debugLib.enable("GoToSocial"); | ||||
| const debug = debugLib("GoToSocial"); | ||||
| 
 | ||||
| const outputEmitter = new EventEmitter(); | ||||
| 
 | ||||
| const splitCSS = require("./split-css")(outputEmitter); | ||||
| const out = require("./output-path"); | ||||
| 
 | ||||
| const postcssPlugins = [ | ||||
| 	"postcss-import", | ||||
| 	"postcss-nested", | ||||
| 	"autoprefixer", | ||||
| 	"postcss-custom-prop-vars", | ||||
| 	"postcss-color-mod-function" | ||||
| ].map((plugin) => require(plugin)()); | ||||
| 
 | ||||
| function browserifyConfig(devMode, { transforms = [], plugins = [], babelOptions = {} }) { | ||||
| 	if (devMode) { | ||||
| 		plugins.push(require("watchify")); | ||||
| 	} else { | ||||
| 		transforms.push([ | ||||
| 			require("uglifyify"), { | ||||
| 				global: true, | ||||
| 				exts: ".js" | ||||
| 			} | ||||
| 		]); | ||||
| 	} | ||||
| 
 | ||||
| 	return { | ||||
| 		cache: {}, | ||||
| 		packageCache: {}, | ||||
| 		transform: [ | ||||
| 			[ | ||||
| 				babelify.configure({ | ||||
| 					presets: [ | ||||
| 						[ | ||||
| 							require.resolve("@babel/preset-env"), | ||||
| 							{ | ||||
| 								modules: "cjs" | ||||
| 							} | ||||
| 						], | ||||
| 						require.resolve("@babel/preset-react") | ||||
| 					] | ||||
| 				}), | ||||
| 				babelOptions | ||||
| 			], | ||||
| 			...transforms | ||||
| 		], | ||||
| 		plugin: [ | ||||
| 			[require("icssify"), { | ||||
| 				parser: require("postcss-scss"), | ||||
| 				before: postcssPlugins, | ||||
| 				mode: 'global' | ||||
| 			}], | ||||
| 			[require("css-extract"), { out: splitCSS }], | ||||
| 			...plugins | ||||
| 		], | ||||
| 		extensions: [".js", ".jsx", ".css"], | ||||
| 		basedir: path.join(__dirname, "../"), | ||||
| 		fullPaths: devMode, | ||||
| 		debug: devMode | ||||
| 	}; | ||||
| } | ||||
| 
 | ||||
| module.exports = function gtsBundler(devMode, bundles) { | ||||
| 	if (devMode) { | ||||
| 		require("./dev-server")(outputEmitter); | ||||
| 	} | ||||
| 
 | ||||
| 	Promise.each(bundles, (bundleCfg) => { | ||||
| 		let transforms, plugins, entryFiles; | ||||
| 		let { outputFile, babelOptions } = bundleCfg; | ||||
| 
 | ||||
| 		if (bundleCfg.factors != undefined) { | ||||
| 			let factorBundle = [require("factor-bundle"), { | ||||
| 				outputs: Object.values(bundleCfg.factors).map((file) => { | ||||
| 					return out(file); | ||||
| 				}), | ||||
| 				threshold: function(row, groups) { | ||||
| 					// always put livereload.js in common bundle
 | ||||
| 					if (row.file.endsWith("web/source/lib/livereload.js")) { | ||||
| 						return true; | ||||
| 					} else { | ||||
| 						return this._defaultThreshold(row, groups); | ||||
| 					} | ||||
| 				} | ||||
| 			}]; | ||||
| 
 | ||||
| 			plugins = [factorBundle]; | ||||
| 
 | ||||
| 			entryFiles = Object.keys(bundleCfg.factors); | ||||
| 		} else { | ||||
| 			entryFiles = bundleCfg.entryFiles; | ||||
| 		} | ||||
| 
 | ||||
| 		if (devMode) { | ||||
| 			entryFiles.push(path.join(__dirname, "./livereload.js")); | ||||
| 		} | ||||
| 
 | ||||
| 		let config = browserifyConfig(devMode, { transforms, plugins, babelOptions, entryFiles, outputFile }); | ||||
| 
 | ||||
| 		return Promise.try(() => { | ||||
| 			return browserify(entryFiles, config); | ||||
| 		}).then((bundler) => { | ||||
| 			bundler.on("error", (err) => { | ||||
| 				console.error(err.message); | ||||
| 			}); | ||||
| 			Promise.promisifyAll(bundler); | ||||
| 
 | ||||
| 			function makeBundle(cause) { | ||||
| 				if (cause != undefined) { | ||||
| 					debug(chalk.yellow(`Watcher: update on ${cause}, re-bundling`)); | ||||
| 				} | ||||
| 				return Promise.try(() => { | ||||
| 					return bundler.bundleAsync(); | ||||
| 				}).then((bundle) => { | ||||
| 					if (outputFile != "_delete") { | ||||
| 						let updates = new Set([outputFile]); | ||||
| 						if (bundleCfg.factors != undefined) { | ||||
| 							Object.values(bundleCfg.factors).forEach((factor) => { | ||||
| 								updates.add(factor); | ||||
| 								debug(chalk.magenta(`JS: writing to assets/dist/${factor}`)); | ||||
| 							}); | ||||
| 						} | ||||
| 						outputEmitter.emit("update", {type: "JS", updates: Array.from(updates)}); | ||||
| 						return fs.writeFile(out(outputFile), bundle); | ||||
| 					} | ||||
| 				}).catch((e) => { | ||||
| 					debug(chalk.red("Fatal error in bundler:"), bundleCfg.outputFile); | ||||
| 					if (e.name == "CssSyntaxError") { | ||||
| 						// contains useful info about error + location, but followed by useless
 | ||||
| 						// actual stacktrace, so cut that off
 | ||||
| 						let stack = e.stack; | ||||
| 						stack.split("\n").some((line) => { | ||||
| 							if (line.startsWith("    at Input.error")) { | ||||
| 								return true; | ||||
| 							} else { | ||||
| 								debug(line); | ||||
| 								return false; | ||||
| 							} | ||||
| 						}); | ||||
| 					} else { | ||||
| 						debug(e.message); | ||||
| 					} | ||||
| 				}); | ||||
| 			} | ||||
| 
 | ||||
| 			if (devMode) { | ||||
| 				bundler.on("update", makeBundle); | ||||
| 			} | ||||
| 			return makeBundle(); | ||||
| 		}); | ||||
| 	}).then(() => { | ||||
| 		if (devMode) { | ||||
| 			debug(chalk.yellow("Initial build finished, waiting for file changes")); | ||||
| 		} else { | ||||
| 			debug(chalk.yellow("Finished building")); | ||||
| 		} | ||||
| 	}); | ||||
| }; | ||||
| 
 | ||||
| outputEmitter.on("update", (u) => { | ||||
| 	u.updates.forEach((outputFile) => { | ||||
| 		let color = (str) => str; | ||||
| 		if (u.type == "JS") { | ||||
| 			color = chalk.magenta; | ||||
| 		} else { | ||||
| 			color = chalk.blue; | ||||
| 		} | ||||
| 		debug(color(`${u.type}: writing to assets/dist/${outputFile}`)); | ||||
| 	}); | ||||
| }); | ||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue