{"id":20645500,"url":"https://github.com/pedrohenriques/web_bundler_minimizer","last_synced_at":"2026-04-18T18:31:51.950Z","repository":{"id":36864495,"uuid":"41171462","full_name":"PedroHenriques/Web_Bundler_Minimizer","owner":"PedroHenriques","description":"Bundle and Minimize your Web files. Light weight and stand alone (no extra packages/dependencies required). Easy and quick to configure.","archived":false,"fork":false,"pushed_at":"2017-09-05T21:09:12.000Z","size":92,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-01-17T09:33:50.055Z","etag":null,"topics":["css-minifier","js-minifier","minifier","minimized-files","ts-import-solver","ts-loader","web-bundling"],"latest_commit_sha":null,"homepage":"","language":"Ruby","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/PedroHenriques.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2015-08-21T18:37:24.000Z","updated_at":"2017-05-28T11:56:14.000Z","dependencies_parsed_at":"2022-09-10T14:20:56.775Z","dependency_job_id":null,"html_url":"https://github.com/PedroHenriques/Web_Bundler_Minimizer","commit_stats":null,"previous_names":[],"tags_count":3,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/PedroHenriques%2FWeb_Bundler_Minimizer","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/PedroHenriques%2FWeb_Bundler_Minimizer/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/PedroHenriques%2FWeb_Bundler_Minimizer/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/PedroHenriques%2FWeb_Bundler_Minimizer/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/PedroHenriques","download_url":"https://codeload.github.com/PedroHenriques/Web_Bundler_Minimizer/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":242714052,"owners_count":20173581,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["css-minifier","js-minifier","minifier","minimized-files","ts-import-solver","ts-loader","web-bundling"],"created_at":"2024-11-16T16:20:08.099Z","updated_at":"2026-04-18T18:31:46.899Z","avatar_url":"https://github.com/PedroHenriques.png","language":"Ruby","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Bundler and Minimizer for Web files  \n\n**Bundle and Minimize your Web Files.**  \n**Supports JavaScript, TypeScript, CSS, SCSS and SASS files.**\n\nLight weight and stand alone (no extra packages/dependencies required). Easy and quick to configure.  \n\nThis application is built in Ruby, as such your computer needs to have Ruby installed. You can find the Ruby install for your system at ([www.ruby-lang.org](https://www.ruby-lang.org/en/)).  \n\n\n## What this application will do for you  \n\nThis application will bundle your stylesheets into 1 CSS file and your code files into 1 JavaScript file, allowing you to better organize your code in development, but without requiring the visitors of your website to download multiple files, which will increase the load times of your website.  \n\nFurthermore, this application will minimize those files into 1 line and remove any unnecessary characters, significantly reducing the size of the files your website visitors need to download.  \n\nAnother feature of this application is the full support for TypeScript, SCSS and SASS files.  \nTypeScript and JavaScript files will be bundled together, as well as CSS, SCSS and SASS being bundled together.  \n\nThis application will handle calling for the compilation of these files, using their respective compilers, and in the case of TypeScript files, creating a \"combined\" file that has all the files in an import chain together, with all the import and export statements resolved.\n\nAll of these features make your life as a developer better and the experience of your website visitors better.   \n\n\n## Setup Instructions and Batch File  \n\nIn order to run the program the file `main.rb` must be called from the command line or terminal.  \n\nThis program uses a **configuration file** to define its operating parameters. This file will be searched for, by the program, starting from the current working directory used to execute the `main.rb` file and following its sub-directories.  \n\nTo facilitate calling the program this repository comes with a **batch file**.  \n\nIn the batch file the line `ruby path\\to\\main.rb` must be adjusted by changing `path\\to\\main.rb` with the absolute path to the `main.rb` file in your system.  \n\n\n## Supported File Types  \n\nCurrently this application supports the following file types:  \n- js\n- ts\n- css\n- scss\n- sass\n\n## Basic Explanation of What this Program Does  \n\nThe program will search for any files that match each **watch rule** (see below for further detail) removing any files that match any of the **ignore rules** (see below for further detail).  \n\nThe relevant files for each watch rule will then be processed. Depending on their file type they might be crawled, compiled and combined or used as they are (see below for further detail).  \n\nIf a watch rule has the option to **join**, then all relevant `.js` files, whether they are native JavaScript files or the result of a TypeScript compilation, will be bundled together into 1 JavaScript file and all relevant `.css` files, whether they are native CSS files or the result of a SASS compilation, will be bundled together into 1 CSS file.  \nIf the option **nojoin** was given instead, then each relevant file will be handled individual and produce 1 output file.  \n\nFinally, if the program is running with the **min** option (see below for further detail) then each output file generated by each of the watch rules will be minimized.  \n\nIn order to decide if an output file needs to be rebuilt, all relevant files added to it will be checked for changes after the output file was built. If any relevant file was changed any output file using it will be rebuilt.  \n\nIf any of the relevant files are non JavaScript or CSS files, ex: TypeScript, SCSS or SASS, then they will be crawled to find all the files they import.  \nIf any file in the import chain is modified, the respective entry point file will be recompiled and the output file rebuilt.  \n\n\n## Use Instructions  \n\nOnce the application starts, you will be prompted for a command.  \n\n### **The valid commands are:**  \n\n-\u003e **run**:  \n\nScans the relevant files, based on the \"watch\" and \"ignore\" properties of the configuration file, and checks if any processing needs to be done.  \nIf any relevant source file is a TypeScript, SCSS or SASS file, the program will call for their compilation and the resulting JavaScript or CSS files added to the output bundle file.  \n\nThe syntax for this command is: `run [sleep_timer] [flags]`  \n\n- `sleep_timer`: [OPTIONAL] integer or float with the number of seconds to wait between each scan cycle (only relevant if running in watch mode)\n\n- `flags`: [OPTIONAL] set of flags to apply when running the scan on the relevant files\n\n\n-\u003e **build**:  \n\nBuilds all the output files, compiles all files that need compilation and executes any necessary processing, even if no changes were made to the source files.  \nOnce the output files have been built the build command ends.  \n\nThis command is equivalent to calling `run -f --no-watch`  \n\nThe syntax for this command is: `build [flags]`  \n\n- `flags`: [OPTIONAL] set of flags to apply when building the output files\n\n\n-\u003e **help**:  \n\nShows help information about the valid commands and their syntax.  \n\nThe syntax for this command is: `help [command]`  \n\n- `command`: [OPTIONAL] name of the command detailed information should be displayed\n\n\n-\u003e **init**:  \n\nCreates a configuration file in the current working directory.  \n\n\n-\u003e **exit**:  \n\nTerminates the program.  \n\n\n### **The valid flags are:**  \n\nFlag | Commands | Description\n--- | --- | ---\n`-w`\u003cbr\u003e`--watch` | run | runs the program in \"watch mode\", which will make the program continuously scan for changes to the relevant files for the watch and ignore rules and rebuild the output files when needed\n`--no-watch` | run, build | the program will check if the output files need to be (re)built once and then stop the scan\n`-f`\u003cbr\u003e`--force` | run, build | forces all output files to be (re)built, including the compilation of all source files that need compilation.\u003cbr\u003eIf the program is in \"watch mode\" only the first cycle will be affected\n`-m`\u003cbr\u003e`--min` | run, build | minimizes output files\n`--no-min` | run, build | doesn't minimize output files\n\n\n## Watch and Ignore Rules  \n\nThe core functionality of the program is centered on the concepts of **watch rules** and **ignore rules**.  \n\nThe watch rules set the paths and options used to find the files that the program should handle.  \n\nThe ignore rules set the paths and options used to ignore some files that might be captured by the watch rules.  \n\nEach watch rule is handled individually and will produce the necessary output files, depending on the number of relevant files matching it and the options affect it.  \n\nAll watch rules will be matched against all ignore rules and any relevant files that match, at least, 1 ignore rule will be ignored.  \n\nThe watch and ignore rules are set in the configuration file explained in the next section.  \n\n\n## Configuration File  \n\nThe program expects to find a file named `bundler.config.json` somewhere in the project's directory tree.  \n\nThe program will search for this file when it starts execution, starting at the current working directory from which the program was executed and going through all its subfolders.  \n**NOTE:** If a configuration file can't be found, the program will terminate.  \n\nAny **relative paths** provided in the configuration file will be considered to be relative to the configuration file's path.  \n\nIf changes are made to the configuration file, there is no need to restart the program. The changes will take effect on the next scan cycle.  \n\n### Syntax  \n\nThe `bundler.config.json` file accepts the following syntax:  \n\n```\n{\n\t\"watch\": [],\n\n\t\"ignore\": [],\n\n\t\"options\": {}\n}\n```\n\n-\u003e The **watch** mandatory property contains an *Array* with each value being a *Hash* representing a **watch rule**, accepting the following syntax:  \n\n```\n\"watch\": [\n\t{\n\t\t\"paths\": [\"watch path 1\", \"watch path 2\", ...],\n\t\t\"out\": \"path to the directory where the output files will be stored\",\n\t\t\"opts\": [\"option 1\", \"option 2\", ...],\n\t\t\"scss_in\": [\"path to SCSS file 1\", \"path to SCSS file 1\", ...],\n\t\t\"scss_out\": \"path to the directory where the compiled SCSS files will be stored\",\n\t\t\"sass_in\": [\"path to SASS file 1\", \"path to SASS file 1\", ...],\n\t\t\"sass_out\": \"path to the directory where the compiled SASS files will be stored\",\n\t\t\"ts_in\": [\"path to TypeScript file 1\", \"path to TypeScript file 1\", ...],\n\t\t\"ts_out\": \"path to the directory where the compiled TypeScript files will be stored\"\n\t},\n\n\t{\n\t\t...\n\t}\n]\n```\n\nProperty | Optional | Value Type | Default Value | Description\n--- | --- | --- | --- | ---\n`paths` | no | array of strings |  | contains the paths, absolute or relative, pointing to files or directories relevant to this watch rule\n`out` | no | string |  | path, relative or absolute, to the directory where all the output files produced by this watch rule will be stored\n`opts` | yes | array of strings | [\"css\", \"scss\", \"sass\", \"js\", \"ts\", \"join\"] | options regulating this watch rule.\u003cbr\u003ethe valid options are:\u003cbr\u003e`css`: include CSS files\u003cbr\u003e`scss`: include SCSS files\u003cbr\u003e`sass`: include SASS files\u003cbr\u003e`js`: include JS files\u003cbr\u003e`ts`: include TS files\u003cbr\u003e`nosub`: don't search in sub-directories\u003cbr\u003e`join`: bundle files together\u003cbr\u003e`nojoin`: don't bundle files together\n`scss_in` | yes | array of strings |  | paths, relative or absolute, to the entry point SCSS files\u003cbr\u003ethese are the files that will be crawled for their imports and then provided to the SASS compiler for compilation\n`scss_out` | yes | string |  | path, relative or absolute, to the directory where all the compiled SCSS files, produced by the SASS compiler, will be stored\n`sass_in` | yes | array of strings |  | paths, relative or absolute, to the entry point SASS files\u003cbr\u003ethese are the files that will be crawled for their imports and then provided to the SASS compiler for compilation\n`sass_out` | yes | string |  | path, relative or absolute, to the directory where all the compiled SASS files, produced by the SASS compiler, will be stored\n`ts_in` | yes | array of strings |  | paths, relative or absolute, to the entry point TypeScript files.\u003cbr\u003ethese are the files that will be crawled for their imports and then provided to the TypeScript compiler for compilation\n`ts_out` | yes | string |  | path, relative or absolute, to the directory where all the compiled TypeScript files, produced by the TypeScript compiler, will be stored\n\n**NOTE:** the following requirements are enforced by the program:  \n\n- If the option `ts` is provided in a watch rule then it must contain the property `ts_in`, even if with an empty array  \n- If the option `scss` is provided in a watch rule then it must contain the property `scss_in`, even if with an empty array  \n- If the option `sass` is provided in a watch rule then it must contain the property `sass_in`, even if with an empty array  \n\n**NOTE:** If no `ts_out`, `scss_out` or `sass_out` properties are provided and there are `.ts`, `.scss` or `.sass` relevant files to process, the directory where the compiled files will be stored is the source file's directory.  \n\n**NOTE:** In the specific case of TypeScript files, if a path to a `tsconfig.json` files is provided, then the program will ignore any value provided in `ts_out` and instead parse the `tsconfig.json` file to find the path where the TypeScript compiler will actually store the compiled files.  \nThe program will search for the **outDir** key of the **compilerOptions** property and if it doesn't exist then each compiled file will be stored in the same directory as their source file.  \n\n\n-\u003e The **ignore** optional property contains an *Array* with each value being a *Hash* representing an **ignore rule**, accepting the following syntax:  \n\n```\n\"ignore\": [\n\t{\n\t\t\"paths\": [\"ignore path 1\", \"ignore path 2\", ...],\n\t\t\"opts\": [\"option 1\", \"option 2\", ...]\n\t},\n\n\t{\n\t\t...\n\t}\n]\n```\n\nProperty | Optional | Value Type | Default Value | Description\n--- | --- | --- | --- | ---\n`paths` | no | array of strings |  | contains the paths, absolute or relative, pointing to files or directories relevant to this ignore rule\n`opts` | yes | array of strings | [\"css\", \"scss\", \"sass\", \"js\", \"ts\"] | options regulating this ignore rule.\u003cbr\u003ethe valid options are:\u003cbr\u003e`css`: include CSS files\u003cbr\u003e`scss`: include SCSS files\u003cbr\u003e`sass`: include SASS files\u003cbr\u003e`js`: include JS files\u003cbr\u003e`ts`: include TS files\u003cbr\u003e`nosub`: don't search in sub-directories\u003cbr\u003e`nojoin`: these files are only to be ignored for watch rules with the join option\n\n\n-\u003e The **options** optional property contains a *Hash* with key/value pairs defining various parameters of how the program will operate, accepting the following syntax:  \n\n```\n\"options\": {\n\t\"watch_mode\": true or false,\n\t\"minimize\": true or false,\n\t\"sleep_timer\": positive integer or float,\n\t\"sass_opts\": \"options to use when calling the SASS compiler\",\n\t\"tsc_opts\": \"options to use when calling the TypeScript compiler\",\n\t\"tsconfig\": \"path to a tsconfig.json file\"\n}\n```\n\nProperty | Optional | Value Type | Default Value | Description\n--- | --- | --- | --- | ---\n`watch_mode` | yes | boolean | false | true will set the program to run in \"watch mode\"\u003cbr\u003efalse will set the program to not run in \"watch mode\"\n`minimize` | yes | boolean | false | true will set the program to minimize all output files\u003cbr\u003efalse will set the program to not minimize output files\n`sleep_timer` | yes | integer or float | 5.0 | number of seconds the program will wait between each scan cycle\u003cbr\u003eonly relevant if the program is in \"watch mode\"\n`sass_opts` | yes | string | \"\" | options that will be used every time the SASS compiler is called\n`tsc_opts` | yes | string | \"-m commonjs -t es5 -d  --outDir [the watch rule's out property value]\" | options that will be used every time the TypeScript compiler is called\n`tsconfig` | yes | string |  | path, relative or absolute, to a `tsconfig.json` file to be used when the TypeScript compiler is called, instead of the **tsc_opts**\n\n**NOTE:** Further information about the configuration syntax can be found in the file located at `data/config_validation.json`.  \n\n**NOTE:** Regarding the `opts` property of both the **watch** and **ignore** fields of the configuration file, the values `css`, `scss`, `sass`, `js` and `ts` are only relevant for paths that point to a directory, where these files types will be searched for.  \nThis means that if a watch or ignore rule only has paths pointing to files, then there is no need to add any of these `opts` values, since no files will be mass searched for and thus they will have no effect.  \n\n\n### Configuration Parameter Hierarchy  \n\nEach configuration parameter described above can be set in some or all of the following ways, with the priority being the following:  \n\n- command line arguments\n- configuration file --\u003e note that not all configuration options have a configuration file equivalent\n- program default values\n\n\n## Important Assumption made by the Program  \n\nThe program assumes that any **/** character used as a division operator will have, at least, 1 whitespace after the **/** and the divisor.  \n\nThe reason for this assumption is that the program needs to be able to identify regex objects, which also use the **/** character as their delimiter.  \nThis creates a potential scenario where a regex object can have the exact same syntax as an arithmetic operation containing at least 2 division operators.  \n\nTo distinguish between the 2 cases either a syntax rule that is unique to only one of the cases is used or searching for regex object requires an algorithm that parses the context of a file's content.  \n\nThis program took the solution of forcing a syntax rule that is unique to the division operator, which is that it will have, at least, 1 whitespace after itself.  \n\nConsider the following example:  \n\n**code 1**  \n```\nvar gi = 4;\n\nvar result = 24 / 3 + Math.randdom() * 10 /gi;\n```\n\n**code 2**  \n```\nvar re = / 3 + Math.randdom() * 10 /gi;\n```\n\nBoth of these codes are valid JavaScript code and yet only by analyzing their context can the distinction between an arithmatic operation and a regex object be made.  \n\nHowever, by forcing at least 1 whitespace after the **/** character with the meaning of a division operator the distinction is much clearer.  \n\nThe text in **code 1** should be:  \n```\nvar gi = 4;\n\nvar result = 24 / 3 + Math.randdom() * 10 / gi;\n```\n\nThe minimized versions of these codes would be:  \n\n**code 1**  \n```\nvar gi=4;var result=24/3+Math.randdom()*10/gi;\n```\n\n**code 2**  \n```\nvar re=/ 3 + Math.randdom() * 10 /gi;\n```\n\n\n## TypeScript Files  \n\n**IMPORTANT:** This program requires TypeScript to be installed as a **global** node module.  \n\nThis program supports TypeScript files, which can be bundled together with other TypeScript and JavaScript files.  \n\nTypeScript files, unlike JavaScript files, will not be captured by watch rule paths automatically just by adding the `ts` option to that rule.  \nThis is due to the fact that TypeScript files can import other files, which means that not all `.ts` files are relevant individually.  \n\nThe only TypeScript files that will be considered relevant for a watch rule are the ones explicitly provided as **entry point** files, in that rule's `ts_in` property.  \n\nThe program will crawl all the entry point files and build a list of all files being imported by them, as well as crawling those imports and so on, building a complete import chain.  \nThis allows the program to scan every file in the import chain and if any of them has been changed, the respective entry point file will be recompiled, by the TypeScript compiler, and any output files from watch rules that use that entry point file will be rebuilt.  \n\nThe way the program resolves module imports is by applying the same rules used by NodeJS, outlined in the [documentation](https://nodejs.org/dist/latest-v8.x/docs/api/modules.html#modules_all_together), with the following caveats:  \n- Files with the `.node` extension are not considered  \n- Imports of NodeJS core modules are not considered\n\nIn terms of the compilation options passed to the TypeScript compiler, the program will use the following priority:  \n\n- use a `tsconfig.json` file, if a path to one was provided in the program's configuration file\n- use the specific value for the `tsc_opts` option, if one was provided\n- use the default value for the `tsc_opts` option\n\n**Another feature** of this program is that it will produce a \"combined\" file for each TypeScript entry point file which contains the entry point file and all files in its import chain combined into 1 JavaScript file, with all import and export statements resolved.  \nThese \"combined\" files will be stored in the same directory as the compiled files from the TypeScript compiler, and its these files that will be added to the watch rule's output file.  \n\n**NOTE:** This program was designed to handle TypeScript files compiled using the **commonjs** compiler module.  \nIf any other compiler module is used the program might not be able to resolve all the import and export statements in the resulting JavaScript file.  \n\n**NOTE:** By default the program will not consider any JavaScript file that is the result of the compilation of a TypeScript file as relevant, unless it is the \"combined\" JavaScript file built from an entry point TypeScript file.  \nIf a watch rule is intended to affect those JavaScript files, then that rule can't have the `ts` option, or if it has an empty array must be given to the `ts_in` property.  \n\n\n## SCSS and SASS Files  \n\nThis program supports SCSS and SASS files, which can be bundled together with other SCSS, SASS and CSS files.  \n\nSimilarly to TypeScript files, these files will be crawled and an import chain will be built for each SCSS and SASS **entry point** file.  \n\nWhenever any file in an import chain is modified, the respective entry point file will be recompiled by the SASS compiler and any output files, for that watch rule, using that entry point will be rebuilt.  \n\nSCSS and SASS files, unlike CSS files, will not be captured by watch rule paths automatically just by adding the `scss` or `sass` options to that rule.  \n\nThe only SCSS and SASS files that will be considered relevant for a watch rule are the ones explicitly provided as **entry point** files, in that rule's `scss_in` and `sass_in` properties.  \n\n**NOTE:** By default the program will not consider any CSS file that is the result of the compilation of an SCSS or SASS file as relevant, unless it is the CSS file built from an entry point TypeScript file.  \nIf a watch rule is intended to affect those CSS files, then that rule can't have the `scss` and/or `sass` option, or if it has an empty array must be given to the `scss_in` and/or `sass_in` property.  \n\n\n## Files Produced by this Program  \n\nThe program will produce the following files:  \n\n- `bundle.css` and `bundle.js`: These output files will be produced for a watch rule that has the `join` option and are the combination of all `css`, `scss` and `sass` files as well as `js` and `ts` respectively  \n- `*.min.css` and `*.min.js`: These output files will produced for a watch rule that has the `nojoin` option and are produced for each individual file that matches that rule's paths (and doesn't match the ignore rules). For these cases if the program isn't in \"minimize mode\" then these files will be a copy of their respective source files\n- `*.combined.js`: These files are produced for each TypeScript entry point file and are the result of combining an entry point `.ts` file and all its import chain files and resolving all the import and export statements.  \nThe program will also make sure that, at maximum, only 1 `use strict;` statement is present and that it is at the top of the file. If none of the source files have this statement then the program will not add it.\n- `*.json`: each output file produced by the program will get a JSON file used to keep track of which files were used to build that output file and if it was minimized or not.  \nThis allows the program to better detect when an output file needs to be rebuilt.\n\n\n## Tagging File Content for Removal  \n\nEvery file added to an output file, directly or as part of an import chain, will be checked for any content inside a pair of tags `/* #bundler remove */`.  \n\nAny content inside a pair of these tags will be removed when that file's content is added to an output file.  \n\n**Example:**  \n\nFor a file contain the text:  \n\n```\n// imports\nimport {TextBox} from \"./TextBox\";\nimport {getTransitionDuration, css_transition_dur_} from \"../main\";\n\n/* #bundler remove */\n// forward declare these functions to please the requirements of the Engine class\n// these functions will be implemented when reading from the script_box.txt file\nfunction textboxExpandCollapse(id: string, only_expand: boolean): void {}\n/* #bundler remove */\n\n// this class handles the overall flow control of building the page on the client side\n// it will control which text box should be active at any given time\nexport class Engine {\n```\n\nThe text that will be added to an output file would be:  \n\n```\n// imports\nimport {TextBox} from \"./TextBox\";\nimport {getTransitionDuration, css_transition_dur_} from \"../main\";\n\n// this class handles the overall flow control of building the page on the client side\n// it will control which text box should be active at any given time\nexport class Engine {\n```\n\n**NOTE:** as an advanced information, the regex pattern used by the program to find these tags is `\\/\\*[\\n\\t ]*#bundler remove[\\n\\t ]*\\*\\/` with the **case insensitive** flag.\n\n\n## Multi-line Comments and the Minimization Task  \n\nThe task of minimizing the output files, by default, will remove all in-line and multi-line comments.  \nThere is, however, a way to signal the program that specific multi-line comments are to be kept.  \n\nThere are 2 ways a multi-line comment can be kept in the minimized version:  \n\n- **Intact:**  \n\tThis will retain a multi-line comment exactly as it is, with all line breaks, tabs and white spaces intact.  \n\tThis format is identified by placing `!!` immediately after the multi-line comment start syntax.\n\n- **Collapsed:**  \n\tThis will collapse a multi-line comment into 1 line, i.e., all tabs and multiple consecutive white spaces will be removed; all line breaks will be converted into a single whitespace.  \n\tThis format is identified by placing `!` immediately after the multi-line comment start syntax.\n\n**EX:**  \n\n### 1)  \n\n```\n/*!!****\n\tThis is a multi-line comment\n\tWith line breaks\n*****/\n```\n\nIs minimized into  \n\n```\n/*****\n\tThis is a multi-line comment\n\tWith line breaks\n*****/\n```\n\n### 2)  \n\n```\n/*!****\n\tThis is a multi-line comment\n\tWith line breaks\n*****/\n```\n\nIs minimized into  \n\n```\n/*****This is a multi-line comment With line breaks*****/\n```\n\n\n## Examples  \n\nConsider the following project directory tree:  \n\n```\nmy_app\n |_ css\n    |_ tooltips.css\n |_ js\n    |_ tooltips.js\n |_ node_modules\n    |_ ...\n |_ sass\n    |_ sass1.sass\n    |_ sass2.sass\n |_ scss\n    |_ general.scss\n    |_ mixins.scss\n    |_ main.scss\n |_ ts\n    |_ classes\n       |_ Engine.ts\n       |_ TextBox.ts\n    |_ main.ts\n |_ bundler.config.json\n |_ package.json\n |_ tsconfig.json\n```\n\nAnd the following import relationships exists:  \n\n- `sass1.sass` imports `sass2.sass`\n- `main.scss` imports `general.scss` and `mixins.scss`\n- `main.ts` imports `classes/Engine.ts` and `classes/TextBox.ts`\n\n### 1) Simplest case  \n\nIf the objective is simply to get 1 CSS and 1 JavaScript file that bundles all of these project's files and stores them in an `assets` directory, then the following `bundler.config.json` file will be enough.  \n\n```\n{\n \"watch\": [\n  {\n    \"paths\": [\".\"],\n    \"out\": \"assets\",\n    \"ts_in\": [\"ts/main.ts\"],\n    \"scss_in\": [\"scss/main.scss\"],\n    \"sass_in\": [\"sass/test1.sass\"]\n  }\n ],\n\n \"options\": {\n   \"tsconfig\": \"./\"\n }\n}\n```\n\nThe changes to the project's directory tree after executing the program's `run` or `build` commands will be:  \n\n```\nmy_app\n |_ .sass-cache\n |_ assets\n    |_ bundle.css (*)\n    |_ bundle.css.json (*)\n    |_ bundle.js (*)\n    |_ bundle.js.json (*)\n |_ js\n    |_ classes\n       |_ Engine.js\n       |_ TextBox.js\n    |_ main.combined.js (*)\n    |_ main.js\n    |_ ...\n |_ sass\n    |_ sass1.css\n    |_ sass1.css.map\n    |_ ...\n |_ scss\n    |_ main.css\n    |_ main.css.map\n    |_ ...\n |_ ts\n    |_ declarations\n       |_ ...\n    |_ ...\n |_ ...\n```\n\nThe files that were created by the program are marked with an **(*)** while the rest of the changes are made by the TypeScript and SASS compilers.  \n\n**NOTE:** by not providing the `opts` property to the watch rule, the default value will be used which will search for all file of the supported file types, looking in sub-directories and bundling the relevant files into 1 JavaScript and 1 CSS file.  \n\n**NOTE:** the TypeScript compiler was provided with the path to the `tsconfig.json` file referenced in the `bundler.config.json` file.  \n\n**NOTE:** when providing relative paths in the configuration file, using `.` or `./` is equivalent.  \n\n### 2) Adding different paths for the bundle JS and CSS files  \n\nIf the following changes are made to the configuration file:  \n\n```\n\"watch\": [\n  {\n    \"paths\": [\".\"],\n    \"out\": \"assets/js\",\n    \"opts\": [\"js\", \"ts\", \"join\"],\n    \"ts_in\": [\"ts/main.ts\"]\n  },\n  {\n    \"paths\": [\".\"],\n    \"out\": \"assets/css\",\n    \"opts\": [\"css\", \"scss\", \"sass\", \"join\"],\n    \"scss_in\": [\"scss/main.scss\"],\n    \"sass_in\": [\"sass/test1.sass\"]\n  }\n]\n```\n\nthen the project's directory tree would be:  \n\n```\nmy_app\n |_ assets\n    |_ css\n       |_ bundle.css\n       |_ bundle.css.json\n    |_ js\n       |_ bundle.js\n       |_ bundle.js.json\n |_ ...\n```\n\n### 2) Adding ignore rules  \n\nIf the following addition is made to the configuration file:  \n\n```\n\"ignore\": [\n  {\n    \"paths\": [\"js/tooltips.js\"],\n    \"opts\": [\"nojoin\"]\n  }\n```\n\nthen the file `my_app/js/tooltips.js` will no not be used in any watch rule that is **bundling** files in the output files.  \n\nIn the case of the previous example, the output file located at `my_app/assets/js/bundle.js` will no longer contain the `my_app/js/tooltips.js` file, as long as the first watch rule has the **join** option.  \n\n**NOTE:** if the watch rule had the **nojoin** option instead, this file wouldn't be ignored.  \n\n**NOTE:** if the ignore rule had `\"opts\": []` instead, then this file would always be ignored, regardless of which options the watch rule had.  \n\n\nApplication made by **Pedro Henriques** ([www.pedrojhenriques.com](http://www.pedrojhenriques.com))\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpedrohenriques%2Fweb_bundler_minimizer","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpedrohenriques%2Fweb_bundler_minimizer","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpedrohenriques%2Fweb_bundler_minimizer/lists"}