d-l-l - Easy, automatic, optimized DLL config handler for webpack - Interview with James Wiens
Perhaps one of my favorite webpack performance related tricks is setting up DLLs so that you avoid work. The problem is that maintaining the setup requires time and effort. What if there was a better way?
James Wiens↗ has been exploring a better solution with d-l-l↗.
Can you tell a bit about yourself?
#
👋 I’m a flow state enthusiast and crafting code is my life’s passion. I’m from Vancouver, Canada, eh.
How would you describe d-l-l to someone who has never heard of it?
#
d-l-l makes your webpack build faster in just a few lines, without having to waste time on the slow manual configuration steps required to use the DllPlugin↗.
The DllPlugin lets you pre-build the parts of your code that don’t often change (such as library code). This means when you change the parts that do change more often, webpack only needs to build these parts, which makes builds exponentially faster.
d-l-l adds some helpful utilities for finding and adding dependencies and files that do not often change.
What’s a minimal example using d-l-l?
#
const dll = require('d-l-l')
module.exports = dll
.init()
// Directory to resolve paths from
.dir(__dirname)
// Pass in webpack config
.config(config)
// Filter to only use non-dev dependencies
.pkgDeps((deps, dev, all) => deps)
// Find all src files
.find('src/**/*.+(js|jsx)')
// Filter to files last modified at least a day ago
.lastModifiedFilter({days: 1})
// Return an array of webpack configurations
.toConfig()
How does d-l-l work?
#
d-l-l creates an array of webpack configuration consisting of a DLL-only webpack config followed by the existing config from your webpack.config.js.
Cache files are created in a .fliphub
folder, which allows some smart-ish checks such as:
- Analysis of your webpack config
- Extraction of essential parts from it, such as the output path
- Usage of the configuration passed via
.config()
The cache files also allow d-l-l to add the decorated dll config if no cache folder or files exist or if there are no manifest files showing what was built and where.
When the cache should be cleared is configurable:
- when cache-busting-files↗ are modified
- every X (default 33) builds↗
- a day or more has passed since the last build↗
Advanced Example
#
Now that we’ve covered a bit of background, an advanced use case should be more understandable:
const dll = require('d-l-l')
const configs = dll
.init()
// Verbose debugging
.debug(true)
// Force building of DLL
.shouldBeUsed(true)
// Return original config, makes it easy to swap side-effect free
.og(true)
// Same as in the simple example above
.dir(__dirname)
.config(config)
// Provide resolved dependency paths manually
.deps(['lodash', 'inferno'].map(dep => require.resolve(dep)))
// Filter dependencies in package.json
.pkgDeps((deps, devDeps, allDeps)) => {
// Ignore dependencies that have `dev` in them.
// Development tools are one example.
return deps.filter(dep => !/dev/.test(dep))
})
// Find files matching a glob
.find('src/**/*.+(js|jsx)')
.lastModifiedFilter({days: 1})
// Return an array of webpack configurations
.toConfig()
How does d-l-l differ from other solutions?
#
There are no other solutions. The only other option is do everything d-l-l does yourself manually. Doing this means maintaining the additional DLL configuration and referencing it in your code. The point of d-l-l is to avoid this complexity.
Why did you develop d-l-l?
#
I was developing fliphub↗ and found there was no webpack documentation for the DllPlugin↗. As I researched and experimented with the plugin, I discovered how powerful it was but how clunky it was to configure it.
To expand on what I mean by clunky, the DllPlugin requires two separate webpack configurations! The order is important - the DLL config has to be built before the normal config. If the normal config uses the DLLReferencePlugin↗ before the DLL config has been built, the build will fail.
Adding even more commands to the build process wasn’t going to happen, so d-l-l was born.
What next?
#
d-l-l will be updated with more features. In an ideal future, the core solution it provides would be integrated into webpack core.
The minimum, most effective plan to integrate it into the core would involve the following changes for d-l-l:
- Trim down dependencies
- Improve focus in logic and the code domain
- Extract features enabling ease of use
- Cover edge cases with air-tight tests
- Merge to webpack core
Once that would be done, the whole community could benefit from the functionality.
chain-able
#
All of the libraries I create use chain-able↗, which enables me to easily create interfaces that describe their intentions and make simple solutions for complex problems.
webpack-wrap
#
I plan to create a wrapper library around webpack (webpack-wrap), allowing easy and smart configuration by following this plan:
- Abstract the d-l-l↗ wrapper
- Simplify splitting with the webpack-split-plugin↗
- Enable webpack merging using neutrino↗ presets in your webpack config
- Finish happypack2↗ and chain-able-webpack↗ which allows for:
- Automatic wrapping of configs in a similar fashion
- Automatic traversable path resolving (resolving all relative paths in your config)
- Integration with webpack-cli↗
- Hints for common misconfigurations
What does the future look like for web development in general? Can you see any particular trends?
#
- Tools and language support can be improved. Developers want to use the coolest hottest sugar syntax which sometimes still needs advanced skills.
- Companies competing in open source for developers will promote their particular flavor of the latest and greatest tech.
- Artificial intelligence will be easier to use and more widespread in both open source and private code.
What advice would you give to programmers getting into web development?
#
I couldn’t fit it reasonably in this block, so I made it into a repo: awesome-advice↗.
- 15-minute rule (proverbial)
- If you ask for help on a problem before doing at least 15 minutes of work researching, debugging, and defining your problem, you’re doing the other person a disservice.
- If you wait longer than 45 minutes and you are stuck, you are doing yourself a disservice.
- The three essential skills in programming:
- #1. how to research
- #2. how to research
- #3. how to research
- The better the problem is defined, the better the solution will be
- Have variable names describe their intention↗
- Premature optimization is the root of all evil
- Make it debuggable
- Join the community and contribute
Who should I interview next?
#
Conclusion
#
Thanks for the interview James! I hope this work eventually finds its way to webpack proper. That would make the approach more approachable to a lot of people.
You can find d-l-l on GitHub↗.
See also the following resources for further information: