README.md (5056B)
1 # tacker 2 3 `tacker` takes your files and staples them together. The goal of this project 4 is to be a simple web bundler independent of the disaster that is the modern 5 npm ecosystem. The main use case of `tacker` is bundling single page 6 applications into a single `.html` file for easier distribution. You can of 7 course also use it to quickly get access to modularity when developing 8 userscripts, to inline images into your static page, etc. 9 10 Advanced bundling and optimization techniques are not in scope 11 of `tacker` - try one of the bloated mainstream bundlers instead: 12 - webpack (75 dependencies) 13 - parcel (184 dependencies) 14 - browserify (175 dependencies) 15 - ... 16 17 `tacker` was written as an experimental project in the new 18 [hare programming language](https://harelang.org/). 19 20 ## features 21 - entrypoints: 22 - HTML 23 - `<script src="...">` tags 24 - `<link rel="stylesheet" href="...">` tags 25 - binary data as base64 (`<audio>`, `<embed>`, `<img>`, `<source>`, 26 `<track>`, `<video>`) 27 - CSS 28 - other style sheets (`@import url(...)`) 29 - binary data as base64 (e.g. `background-image: url(...)`) 30 - JS 31 - a subset of CommonJS modules (see below for important drawbacks) 32 - `require(...)` 33 - `module.exports` and `exports` 34 35 The "conceptual module name space root" is the working directory. This means 36 that required paths which are not relative are resolved from the cwd. For 37 security reasons only files in the cwd can be bundled. This can be changed with 38 the `-p` option. Input and output file name stay relative to the cwd. The 39 `.js` in `require()` imports is optional. 40 41 `tacker` does not aim to be 100% spec-compliant. The goal is to work in all 42 common scenarios without laying to much emphasis on obscure edge cases. It is a 43 tacker after all - not an industrial robot. Though unlike a real-world tacker 44 your security should not be at hazard. Malicious source files can obviously 45 take over your bundled page but they can never take over your system. 46 47 ## known bugs & missing features 48 49 ### require() 50 CommonJS was chosen out of personal preference and its simplicity compared to 51 ES Modules (tree-shaking optimizations enabled by ES Modules would not be 52 implemented either way). The parser is rather simple though. To confirm to the 53 CommonJS spec arbitrary javascript expressions (as the argument to `require()`) 54 would need to be able to be evaluated at bundle-time. As `require` is just a 55 value and not special syntax the same is the case for the whole program as 56 every function could be possibly rebound to `require`. This requires the 57 complete execution of the program at bundle-time to be able to reason about 58 possible aliases to `require`. This is impossible and thus `require()` will be 59 treated as special syntax. This implementation (and in fact every CommonJS 60 bundler) is thus wrong but should work for every sane usage of `require()`. 61 62 The `require()` macro expects a string literal with single or double quotes as 63 single argument. Whitespace between `(` and `"`/`'` or between `"`/`'` and `)` 64 is forbidden. Currently no escape sequences are allowed as this would add a lot 65 of complexity and is not needed for sane file names. This feature may be added 66 in the future. 67 68 Correctly expanding the `require()` macro requires recognizing string 69 literals (to not cause bugs by changing string content). This in turn requires 70 correctly recognizing regex literals as they could contain quote characters and 71 as far as I know this requires parsing the whole AST (how to decide if `/5/` is 72 a regex or part of an arithmetic expression?). A similar problem arises for 73 template literals. To avoid this complexity `tacker` only reads until reaching 74 the first character that could be start of a string, regex or template literal. 75 This means that module imports have to be at the top of each source file which 76 is the case already for most projects. All potentially skipped `require()` 77 calls will be announced as a warning. 78 79 ### script end tags & regex literals 80 When inlining javascript in html, the script cannot contain script end tags 81 (`</script>`). To handle this all occurrences of `</script` will be replaced by 82 `<\/script`. This works in string literals and comments and should never occur 83 in normal code. I am however not sure about regex literals - there could be 84 very rare edge cases where these break. 85 86 ### external resources 87 Bundling of external scripts, images, etc. is currently forbidden and `tacker` 88 will throw an error. There are two alternative behaviors: 89 90 1. Bundling the external resource: I think it is a bad idea to bundle random 91 assets from the internet. 92 2. Allowing references to external resources without bundling them: This would 93 be a better way of handling external resources but it creates a runtime 94 dependency which is not very sustainable considering link rot. 95 96 It would be possible to enable behavior (2) via a command argument flag but I 97 currently do not see the point in implementing this feature. 98 99 ## todo 100 - css bundling 101 - larger test coverage 102 - online mode to bundle third party scripts or css