Demo for the Alma/Primo API as well as revisiting webpack dev workflow. Overkill for this project, but how else are you going to keep up to date?
- Basic
npm
+webpack
dependency chain - Basic
webpack
watch set upnode-sass
webpack-dev-server
html-webpack-plugin
- Make basic Primosearch call
- Parse data
- Augment data with cover image of video (using OMDB)
- Sort table by expiration date (had to parse hand inputted date field)
- Using
DataTables
-- though is there a better way?
While I'm still on the fence about whether my tiny projects benefit from Webpack, I'll use this as an opportunity to work through what I learned. As ever, when I step away from JS development for a minute, it always takes waaay longer than I expect to get back in. The issue is: What's a minimal toolchain that meets our small projects? Hard to resist following the trends for larger JS webapps.
The idea of using a bundling tool to create flexible builds (conceptually a lot like workflow for compiling binary than old-school webdev, at least to me) is certainly ascendant. Two most popular tools are webpack and browserify, though webpack continues to be more heavily used. Yes, I know they're different, but still ...
I found out a few years ago that I was unnecessarily including gulp/grunt into my workflow -- for simple sass compilation and js uglification, no need to look further than npm
scripts defined in package.json
.
However, I'm pretty interested in ES6 features, which regular old uglify does not support. Plus more flexible browser compatibility ala babel seems like a good idea. That plus built in templating, handling requires, etc., makes webpack interesting to pick up if not strictly necessary. As a side note, as I'm interested in JS static site development, most of which is webpack based (e.g., gatsby), seems useful to at least be familiar.
What are the questions webpack answers?
- How to manage complex javascript dependency trees and deploy them flexibly?
- chunking
- cache busting
- configurable per dependency options (external loading, etc.)
- templating
- How to run a local server with live reload that doesn't (or sucks less) than alternatives?
- How to structure a flexibly preprocessing chain (e.g., uglify, sass, compression, image processing)?
What doesn't it answer?
- Does web development really need to become more like conventional software development and doesn't it take the fun out of it?
Basically: define a launch script in package.json
to launch webpack as configured by webpack.config.js
and you're good.
webpack plugins that seem pretty useful so far:
webpack-dev-server
launches a local server and serves static files from distribution as well as dynamically rendered files as defined in the webpack config (note that this is for dev and does not actually do a complete build)HtmlWebpackPlugin
allows you to define your own HTML template, which seems essential -- unless a fancy React app, unclear why you'd want to futz with shitty JS templatingCleanWebpackPlugin
taken on faith that this is good for deleting stale assets on rebuild
Found that (I didn't quite understand what the dev server was doing vs. running a build) // filename: path.resolve(__dirname, './dist/index.html')
in HTMLWebpackPlugin silently fucks with the ability of the Webpack Dev Server to compile new files rather than serve from memory -- must be enabled/disabled based on mode production or dev.
After futzing with a number of Medium/Stackexchange/other posts, I found Colt to be most useful for webpack v4 -- both the example repo and his YouTube playlist.
- create a
src
folder in the project root for all project scripts and assets,makes things a little easier to keep track of down the line. npm init
&npm install --save-dev
example barebones module list below- create appropriate
npm run
scripts, e.g.:
"build": "npx webpack --config webpack.prod.js",
"start": "npx webpack-dev-server --config webpack.dev.js --open"
- create separate webpack
dev
andprod
config files -- note that you really do need different files to save hassle -- creating a sharedcommon
file that is then imported intoprod
anddev
configs is another helpful pattern, but seemed a little extra dev
config doesn't need much -- this is what's served when running the dev server. Note that this does not invoke all of the parameters/rules/plugins you might have set up for production even if they were included in the file, which is why it seems like a good idea to keep these options separate to avoid confusion. Webpack dev server generates files in memory on the fly for development purposes (obv) -- it does not run through the full build, does not generate new files, etc.prod
config can get complicated (webpack is complicated), this is where the full complement of rules, optimizations, and preprocessing happens -- again, only on build. Caused me unending grief and despair that I didn't clue into how a) webpack defaults are very different for different modes and b) some production parameters will mess up how webpack dev server serves -- a tiny distinction that wasn't made clear in the umpteen tutorials I consulted.
The webpack model relies on annoyingly specific lexicon (IMO) and I thought I could gloss over it, which only resulted in a gnashing of teeth. I wish I head spent two second first trying to understand the underlying model, at least superficially.
- entry Worth noting the obvious that webpack is for Javascript -- everything else is secondary. Similar to but not exactly the
main.js
or whatever you might be used to. Here you designate the entrypoint js file(s) that trigger the rest of the pipeline. However, unlike the js you might be used to, everything needs to be included via ECMAScriptimport
statements -- even non-js assets (really, all css, images, data, need to be imported). - output While the entry parameter is more a metafile and includes much more than the regular old js you might call in a
script
tag, the output parameter is actually just the executable javascript that you intend to include in your page/app. - path Not that complicated but still worth noting that it's pretty dynamic if you think of all the templating and preprocessing going on, for example, resolving differently for webpack dev server than for build.
path
module resolve method (i.e.,path.resolve(__dirname, 'dist/js')
) is your friend. - rules If you want webpack to handle files other than js files and you want to handle them differently from js files you need to write rules specifying how to identify and handle those files (i.e., regex to parse extensions).
- loaders Modules specific to different filetypes that handle those filetypes differently. How to parse, preprocess, and minify scss? How to copy over image or font files without doing anything to them? What if you want to change all the html refs and filenames for those assets to include a content hash in order to override caching?
- plugins Imported modules invoked to do stuff somewhere along the pipeline.
- optimization Modules invoked to do something at the end of the pipeline in production.
webpack
- "webpack"
- "webpack-cli"
- "webpack-dev-server"
- "clean-webpack-plugin"
loaders
- "css-loader"
- "file-loader"
- "html-loader"
- "sass-loader"
- "style-loader"
optimization/preprocessing
- "node-sass"
- "mini-css-extract-plugin"
- allows you to work with css like a normal human rather than have all styles rendered inline and/or declared in js like a weirdo
- "optimize-css-assets-webpack-plugin"
- "terser-webpack-plugin"
- uglify replacement
- "html-webpack-plugin"
- rather than have webpack automagically create an html template for all your js, set your own template -- webpack will still handle injecting js, style, href paths, and other templating as needed