a brilliant quick experimental bundler written in Rust
Packem resolves a module’s dependencies and rehydrates them right into a module graph, a flat checklist containing module interfaces that are basically references to in-memory heap-based mutable information constructions containing particular metadata of a module within the module graph.
Many of the enterprise logic is abstracted into Rust utilizing FFI bindings to allow low stage interactions between each ends. The Rusty binaries can be found as precompiled Node C/C++ addons in Packem’s repo. A cloud-based CI is used to run just a few scripts with pre-gyp installations, yielding OS-specific binaries with assist for later Node variations (8, 9, 10).
This layer of Packem’s core is what’s known as the Logical Context (LC). All the opposite operations that aren’t explicitly prioritized are regressed into Node’s common runtime, which in Packem’s phrases is the Runtime Context (RC). Learn extra on contexts right here.
Theoretically, the module graph is saved flat to keep away from frequent pitfalls that might result in pointless traversals if a tree was utilized in place. This permits the RC to maintain observe of circumstances akin to deep round dependencies or closely nested dynamic imports (code splitting), amongst others, appropriately with minimal efficiency implications or unwanted effects as doable.
Extra particulars will be discovered at Packem’s README.md.
I’ve been having this concept in thoughts however by no means deliberate to execute it till I joined forces with Saddam M. It has actually been in my curiosity to see module bundling as an idea protected for anybody to be taught, perceive and implement. Having individuals battle with configurations, documentation and plugins was extraordinarily horrendous and I’d prefer to take the prospect to vary that. With you. With Packem.
Fast historical past
What I wished was a bundler that does many of the heavy-lifting in a close-to-the-metal language for the person with out requiring any interplay with its internals. Then I discovered Rust. A wise and concise programs language that exhibits off some laudable options like a fearless concurrency mannequin, kind security, and extra! I might count on as a lot from utilizing C/C++ however I’d quite persist with Rust because it’s fairly simple relating to reminiscence administration.
Why one other bundler?
So what’s the take right here? Why do we’d like one other construct software since we have already got superb ones like webpack, Parcel, Rollup, and so forth? I’ll take you together with just a few the reason why. Maybe you may need your individual pursuits in having your growth and manufacturing construct instances lowered closely.
It’s 2019, we don’t want gradual instruments no extra
Though Packem is quicker than webpack 4, it’s greater than twice as quick as Parcel (with multicore compilation). In a benchmark check, we bundled Lodash v4.17.1 with each Packem and Parcel and this was the end result:
By no means take any benches at face worth. You may try it out for your self right here.
The rationale why I didn’t hassle benchmarking Parcel in opposition to webpack was as a result of webpack Four is profoundly sooner than Parcel. I proved this reality through the use of Sean T. Larkin’s personal benches and a thread to it on Twitter will be discovered right here.
As a result of we are able to. Anybody can, proper?
After all, what’s going to take advantage of sense, is as a result of we are able to. We had the thought of getting sooner bundle instances with a Rusty interface both with FFI or WASM (was nonetheless uncertain by then). FFI was extra affordable so far as velocity and DX was involved, so we went with having Packem carried out in Rust FFI bindings.
We skilled just a few thread-related points so we didn’t make a lot use of the obtainable sources. Because of this we used a number of node youngster processes (with node-worker-farm), the identical approach Parcel makes use of for multicore compilation, however for bigger module graphs because it provides a major startup time on high of Node’s uptime when used with smaller module graphs.
This was a difficult half. There have been loads of questions that wanted a great reply to make as much as selecting the correct configuration fashion. Static or dynamic? JSON/YAML/TOML? Our selection was based mostly totally on whether or not we wanted Packem to:
- Have a neater configuration fashion, and
- Be agnostic of different customized person configurations like .babelrc or bundle.json.
Bottomline, we proceeded with a static configuration fashion since we discovered it to be precisely what we would have liked. One thing that might declaratively inform Packem how one can handle the bundle cycle. All the bounds to having a static configuration had been made clear.
JSON simply didn’t lower out due to all of the pointless string quotes, curly & block braces, which is sensible because it’s a information interchanging format. An XML-ish method deserves no respect close to getting used as a configuration format because it makes issues worse than JSON so far as pointless characters are involved. TOML launched loads of new traces, and debugging nested choices didn’t look like eye-appealing since we knew that Packem plugins might get actually nesty.
The ultimate winner was YAML! It was capable of move via all points of being a correct configuration format (for Packem not less than). It:
- Makes configuration painless.
- Makes use of a sublime method.
- Was designed particularly for this use-case (configurations).
Right here’s an instance of a typical Packem configuration (packem.config.yml). Verify for your self and take into consideration writing the identical content material in a JSON/TOML/XML-ish fashion.
FYI, solely the primary two choices are obligatory! 😉
This characteristic isn’t but carried out.
Typically we’d want to make use of a characteristic that doesn’t but exist, may not be carried out in Packem or is very particular to our venture. For that case, you’d have two methods of fixing your wants:
- Create a Packem plugin on your use case (which is the really helpful possibility).
- Construct a customized RC on high of Packem’s binaries.
Utilizing Rust offers us the prospect to reform the LC into different binary codecs, akin to WebAssembly, which can allow Packem to exhibit a number of compile targets:
- A NAPI-based C/C++ addon with platform-specific binaries required by Packem’s default RC.
- A WebAssembly-based binary that’s cross-platform and injected into the RC.
- Packem’s default standalone which makes use of WebAssembly with a browser-compatible implementation of the RC.
The final two aren’t but on the radar since inside refactorings are nonetheless being sorted out.
The superior information is quickly anticipated to point out you how one can construct a customized construct software utilizing Packem’s binaries to suit your personal wants in case you should use Packem exterior the browser and Node environments. These binaries full the whole graph era, and duplicate filtering and different graph-related points. This implies you need to use your customized serializer, file watcher, plugin system, and so forth. It’s very like how one can construct your customized renderer over OpenGL.
- You may nonetheless embrace Packem’s plugin system since it’s going to mean you can combine Packem’s ecosystem of plugins along with your customized bundler.
- When you’re unsure whether or not or not you would want to construct a customized bundler, know that you simply wouldn’t at all times must. Please strive submitting a difficulty first.
- It’s a assure that these binaries will velocity up your workflow relying in your particular use case(s).
- ✂ Code Splitting for growth and manufacturing modes.
- 💻 Improved CLI (` — verbose`) for higher info on bundling cycle.
- 📃 Module Interfaces to permit simple manipulation of the module graph.
- ✔ Correct precedence. Native functionalities match completely into the LC. This implies there’s better probabilities of speedy builds.
- 📤 Export
NativeUtilsfor exterior utilization of native functionalities together with
generateModuleGraphwhich reruns the method of producing a module graph. It’s heavy however nonetheless helpful in circumstances the place you’d want a clone of the present lively module graph. Utilizing it means doubling the construct time, so use it with care.
These are the options we’re hoping to have quickly within the upcoming releases. Along with your efforts we might get bundling performed the appropriate approach. When Packem is at 1.0, we’re anticipating to have full assist for all of the options listed under and the others talked about in Packem’s roadmap.
- A browser-compatible standalone of Packem with the LC in WebAssembly for nearer integration with the underlying system. Axel Rauschmayer already made a characteristic request to have a Node-compatible model in WASM. For the report, we’ll be engaged on each quickly.
- Treeshaking, however superior. Resolving named/unnamed imports and stripping lifeless code ought to be a breeze. This implies you need to use libraries like lodash as an alternative of lodash-es with out worrying whether or not your code might be elided or not.
- Auto Config. Like Zero Config, however defaults-oriented for additional flexibility.
- Superior CLI choices to make growth with Packem a second nature.
- Higher error reporting.
- Extra surroundings targets. Packem can solely bundle for the browser as of now. Ultimately, we count on to assist Node CJS and different codecs as nicely.
- Extra plugins. We want extra plugins! Packem has a set of frequent plugins to get you began faster. However to develop a group, we’ll want an ideal ecosystem of plugins. Verify the frequent plugins obtainable or the plugins part on the positioning to begin growing a plugin instantly.
- And rather more…
Packem hasn’t attain 1.0 but. In case you have discovered Packem to be fascinating in any respect to you, strive contributing to Packem itself by creating plugins, updating the documentation, supporting us financially, representing Packem at conferences or another means. We respect your efforts!
Completely satisfied bundling! 🧡🧡🧡