├── .editorconfig
├── .gitattributes
├── .github
├── baker.jpg
├── dependabot.yml
└── workflows
│ ├── codeql-analysis.yml
│ └── test.yml
├── .gitignore
├── CHANGELOG.md
├── LICENSE
├── README.md
├── bin
└── bake.js
├── example-simple
├── _data
│ └── titles.json
├── _layouts
│ └── template.html
├── baker.config.js
├── index.html
├── other.html
├── scripts
│ ├── Paragraph.svelte
│ ├── app.js
│ ├── sectors.csv
│ └── utils.ts
└── styles
│ └── main.scss
├── example
├── .env
├── _data
│ └── meta.json
├── _layouts
│ ├── base.njk
│ ├── extra.njk
│ ├── header.njk
│ ├── object.json.njk
│ ├── object.njk
│ ├── robots.txt.njk
│ └── sitemap.xml.njk
├── assets
│ ├── demo.json
│ ├── fonts
│ │ ├── benton-gothic-regular.woff
│ │ └── benton-gothic-regular.woff2
│ └── images
│ │ ├── corgi-copy.JPG
│ │ └── corgi.jpg
├── baker.config.js
├── embeds
│ ├── embed_example.html
│ └── embed_example_2.html
├── index.njk
├── scripts
│ ├── Inner.svelte
│ ├── Other.svelte
│ ├── app.js
│ ├── app.svelte
│ ├── cdcr.csv
│ ├── cdcr.json
│ ├── client.ts
│ ├── global.d.ts
│ ├── nested
│ │ └── internal.js
│ └── woo
│ │ └── app.js
├── styles
│ ├── _type.scss
│ ├── _variables.scss
│ └── main.scss
├── three
│ └── four.njk
├── tsconfig.json
└── two.njk
├── lib
├── blocks
│ ├── inject.js
│ ├── script.js
│ └── static.js
├── engines
│ ├── assets.js
│ ├── base.js
│ ├── nunjucks.js
│ ├── rollup.js
│ └── sass.js
├── env.js
├── filters
│ ├── date.js
│ ├── json-script.js
│ └── log.js
├── index.js
├── paths.js
├── polyfills
│ └── dynamic-import.js
├── rollup-plugins
│ ├── css-plugin.js
│ ├── data-plugin.js
│ ├── dataset-plugin.js
│ └── prepend-entry.js
├── utils.js
└── vendor
│ └── dlv.js
├── package-lock.json
├── package.json
├── patches
└── mini-sync+0.3.0.patch
└── svelte.config.js
/.editorconfig:
--------------------------------------------------------------------------------
1 | root = true
2 |
3 | [*]
4 | indent_style = space
5 | indent_size = 2
6 | end_of_line = lf
7 | charset = utf-8
8 | trim_trailing_whitespace = true
9 | insert_final_newline = true
10 |
11 | [*.py]
12 | indent_size = 4
13 |
14 | [*.md]
15 | trim_trailing_whitespace = false
16 |
--------------------------------------------------------------------------------
/.gitattributes:
--------------------------------------------------------------------------------
1 | * text=auto
2 |
--------------------------------------------------------------------------------
/.github/baker.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/datadesk/baker/59c185c8de06c89a4ab979789c2fb2eae44a653e/.github/baker.jpg
--------------------------------------------------------------------------------
/.github/dependabot.yml:
--------------------------------------------------------------------------------
1 | version: 2
2 | updates:
3 | - package-ecosystem: npm
4 | directory: "/"
5 | schedule:
6 | interval: monthly
7 |
--------------------------------------------------------------------------------
/.github/workflows/codeql-analysis.yml:
--------------------------------------------------------------------------------
1 | # For most projects, this workflow file will not need changing; you simply need
2 | # to commit it to your repository.
3 | #
4 | # You may wish to alter this file to override the set of languages analyzed,
5 | # or to provide custom queries or build logic.
6 | #
7 | # ******** NOTE ********
8 | # We have attempted to detect the languages in your repository. Please check
9 | # the `language` matrix defined below to confirm you have the correct set of
10 | # supported CodeQL languages.
11 | #
12 | name: "CodeQL"
13 |
14 | on:
15 | push:
16 | branches: [ "main" ]
17 | pull_request:
18 | # The branches below must be a subset of the branches above
19 | branches: [ "main" ]
20 | schedule:
21 | - cron: '41 16 * * 1'
22 |
23 | jobs:
24 | analyze:
25 | name: Analyze
26 | runs-on: ubuntu-latest
27 | permissions:
28 | actions: read
29 | contents: read
30 | security-events: write
31 |
32 | strategy:
33 | fail-fast: false
34 | matrix:
35 | language: [ 'javascript' ]
36 | # CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python', 'ruby' ]
37 | # Learn more about CodeQL language support at https://aka.ms/codeql-docs/language-support
38 |
39 | steps:
40 | - name: Checkout repository
41 | uses: actions/checkout@v3
42 |
43 | # Initializes the CodeQL tools for scanning.
44 | - name: Initialize CodeQL
45 | uses: github/codeql-action/init@v2
46 | with:
47 | languages: ${{ matrix.language }}
48 | # If you wish to specify custom queries, you can do so here or in a config file.
49 | # By default, queries listed here will override any specified in a config file.
50 | # Prefix the list here with "+" to use these queries and those in the config file.
51 |
52 | # Details on CodeQL's query packs refer to : https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#using-queries-in-ql-packs
53 | # queries: security-extended,security-and-quality
54 |
55 |
56 | # Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
57 | # If this step fails, then you should remove it and run the build manually (see below)
58 | - name: Autobuild
59 | uses: github/codeql-action/autobuild@v2
60 |
61 | # ℹ️ Command-line programs to run using the OS shell.
62 | # 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun
63 |
64 | # If the Autobuild fails above, remove it and uncomment the following three lines.
65 | # modify them (or add more) to build your code if your project, please refer to the EXAMPLE below for guidance.
66 |
67 | # - run: |
68 | # echo "Run, Build Application using script"
69 | # ./location_of_script_within_repo/buildscript.sh
70 |
71 | - name: Perform CodeQL Analysis
72 | uses: github/codeql-action/analyze@v2
73 |
--------------------------------------------------------------------------------
/.github/workflows/test.yml:
--------------------------------------------------------------------------------
1 | name: Test builds
2 |
3 | on: [push]
4 |
5 | jobs:
6 | test:
7 | name: Test
8 | runs-on: ubuntu-latest
9 | strategy:
10 | matrix:
11 | node: ['14', '16', '18', '20', '21']
12 | steps:
13 | - uses: actions/checkout@v3
14 | - uses: actions/setup-node@v3
15 | with:
16 | node-version: ${{ matrix.node }}
17 | cache: npm
18 | - run: npm ci
19 | - run: npm run build
20 | - run: npm run build:simple
21 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Logs
2 | logs
3 | *.log
4 | npm-debug.log*
5 | yarn-debug.log*
6 | yarn-error.log*
7 | lerna-debug.log*
8 |
9 | # Diagnostic reports (https://nodejs.org/api/report.html)
10 | report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
11 |
12 | # Runtime data
13 | pids
14 | *.pid
15 | *.seed
16 | *.pid.lock
17 |
18 | # Directory for instrumented libs generated by jscoverage/JSCover
19 | lib-cov
20 |
21 | # Coverage directory used by tools like istanbul
22 | coverage
23 | *.lcov
24 |
25 | # nyc test coverage
26 | .nyc_output
27 |
28 | # Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
29 | .grunt
30 |
31 | # Bower dependency directory (https://bower.io/)
32 | bower_components
33 |
34 | # node-waf configuration
35 | .lock-wscript
36 |
37 | # Compiled binary addons (https://nodejs.org/api/addons.html)
38 | build/Release
39 |
40 | # Dependency directories
41 | node_modules/
42 | jspm_packages/
43 |
44 | # TypeScript v1 declaration files
45 | typings/
46 |
47 | # TypeScript cache
48 | *.tsbuildinfo
49 |
50 | # Optional npm cache directory
51 | .npm
52 |
53 | # Optional eslint cache
54 | .eslintcache
55 |
56 | # Optional REPL history
57 | .node_repl_history
58 |
59 | # Output of 'npm pack'
60 | *.tgz
61 |
62 | # Yarn Integrity file
63 | .yarn-integrity
64 |
65 | # dotenv environment variables file
66 | .env.test
67 |
68 | # parcel-bundler cache (https://parceljs.org/)
69 | .cache
70 |
71 | # next.js build output
72 | .next
73 |
74 | # nuxt.js build output
75 | .nuxt
76 |
77 | # vuepress build output
78 | .vuepress/dist
79 |
80 | # Serverless directories
81 | .serverless/
82 |
83 | # FuseBox cache
84 | .fusebox/
85 |
86 | # DynamoDB Local files
87 | .dynamodb/
88 |
89 | # example directories to ignore
90 | example/_dist
91 | example/_screenshot
92 | example/_fallbacks
93 | example/.DS_Store
94 | example-simple/_dist
95 | example-simple/.DS_Store
96 |
97 | # IntelliJ
98 | .idea
99 |
100 | .DS_Store
101 |
--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | # Changelog
2 |
3 | All notable changes to this project will be documented in this file.
4 |
5 | The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6 | and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7 |
8 | ## [0.47.7] - 2024-02-13
9 |
10 | ### Added
11 | - Strict timestamp check to fallback image uploads and updated fallback upload step in deploy workflow
12 |
13 | ## [0.47.6] - 2025-01-15
14 |
15 | ### Changed
16 | - Adjusted viewport settings to dynamically fix content height and add 20px bottom padding for fallback images
17 |
18 | ## [0.47.5] - 2024-12-05
19 | - Patched mini-sync to run on 127.0.0.1 and added option `port` option to baker config
20 |
21 | ## [0.47.4] - 2024-11-07
22 | - Updated manifest to correctly source assets in link tags, removing incorrect file references
23 |
24 | ## [0.47.3] - 2024-11-05
25 | - Fix fallback images generation
26 |
27 | ## [0.47.2] - 2024-10-31
28 | - Set `deviceScaleFactor` to 2 for improved screenshot resolution.
29 |
30 | ## [0.47.1] - 2024-10-11
31 | - Added a fixed width (`FIXED_FALLBACK_SCREENSHOT_WIDTH`) to generate mobile-friendly fallback screenshot images
32 |
33 | ## [0.47.0] - 2024-10-09
34 | - Added `screenshot` task to baker for fallback image generation
35 |
36 | ## [0.46.1] - 2024-10-02
37 | - Removed `webHookUrl` from baker.config
38 |
39 | ## [0.46.0] - 2024-08-30
40 | - `prepareCrosswalk` deprecated from baker config in favor of built-in crosswalk data handling.
41 | - Remove `staticAbsoluteBlock`. All static assets use absolute paths now
42 | - Audio file (`.mp3`) is now recognized by `AssetsEngine` and will be included in any hashing.
43 | - Extended Image files to include (`.webp`, `.avif`).
44 | - Added `webHookUrl` option in baker.config
45 |
46 | ## [0.45.0] - 2024-02-03
47 | - Added watcher for changes to `createPages` templates
48 | - Updated dependencies
49 |
50 | ## [0.44.1] - 2023-04-07
51 | - Updated dependencies
52 |
53 | ## [0.44.0] - 2022-12-10
54 | - Added support for rending API endpoints in JSON, sitemaps.xml and robots.txt
55 | - Added `createPages` to the test routine
56 | - Updated dependencies
57 |
58 | ## [0.41.0] - 2022-11-09
59 |
60 | ### Changed
61 | - Updated dependencies
62 |
63 | ## [0.40.0] - 2021-12-04
64 |
65 | ### Changed
66 | - Updated dependencies
67 |
68 | ## [0.39.0] - 2021-11-23
69 |
70 | ### Changed
71 | - Refactored the package to comply with [ES module](https://nodejs.org/api/packages.html#determining-module-system) standards
72 | - Updated dependencies
73 |
74 | ## [0.38.0] - 2021-11-16
75 |
76 | ### Added
77 | - New `nunjucksVariables` config option to set global variables for all templates.
78 |
79 | ### Changed
80 | - Updated dependencies
81 |
82 | ## [0.37.0] - 2021-11-10
83 |
84 | ### Added
85 | - New `NOW` global variable with the current timestamp returned by `new Date()`
86 |
87 | ### Changed
88 | - Updated dependencies
89 |
90 | ## [0.36.0] - 2021-10-30
91 |
92 | ### Added
93 | - Added new `minifyOptions` option to allow users to override the default configuration
94 |
95 | ### Changed
96 | - Updated dependencies
97 |
98 | ## [0.34.0] - 2021-06-23
99 |
100 | ### Changed
101 |
102 | - The Nunjucks engine now uses `FileSystemLoader` for `node_modules` imports (very similar to how Sass engine works via `includePaths`), instead of deferring to `NodeResolveLoader`. That loader is not nearly as useful when `npm` installed packages use the new [`"export": { ... }` format](https://nodejs.org/api/packages.html#packages_exports). Unless packages explicitly declare the non-JS exports you're unable to find them. I don't think we were using that anyway, so it's NBD.
103 |
104 | ## [0.33.0] - 2021-05-05
105 |
106 | ### Added
107 |
108 | - It is now possible to pass compiler options to Svelte via `svelteCompilerOptions` in `baker.config.js`. Good for the rare case of when you need to render them as hydratable.
109 |
110 | ## [0.32.1] - 2021-04-27
111 |
112 | ### Fixed
113 |
114 | - Our custom Rollup `datasetPlugin` and `dataPlugin` have been moved to before `@rollup/plugin-node-resolve` in the Rollup plugin list. In some cases `nodeResolve` would misinterpret the `*:` prefix and blow up the path before these plugins got a chance to do it first.
115 |
116 | ## [0.32.0] - 2021-04-14
117 |
118 | ### Changed
119 | - The `{% static %}` tag will now pass through full URLs as-is when used as the parameter. This lets developers not have to worry about whether a path is project relative or not in loops, and allows templates that work with files to easily account for local and remote files.
120 |
121 | ## [0.31.2] - 2021-02-22
122 |
123 | ### Added
124 | - Add `preventAssignment: true` to `@rollup/plugin-replace` options.
125 |
126 | ### Fixed
127 | - Make sure `process.exit(1)` is called when builds fail.
128 | ## [0.31.1] - 2021-01-31
129 |
130 | ### Fixed
131 |
132 | - Pathing for Svelte CSS also needs to account for path prefixes or else it will be resolved incorrectly in HTML that's not at the root.
133 |
134 | ## [0.31.0] - 2021-01-22
135 |
136 | ### Added
137 |
138 | - Thanks to `@web/rollup-plugin-import-meta-assets` it's now possible to import paths to files within JavaScript and have that be enough to ensure that the file is added to the build. This is _yet another_ method for loading data in baker projects, and likely the best one yet.
139 |
140 | ```js
141 | // Rollup will see this and understand it should add this file to your build
142 | const url = new URL('./data/cities.json', import.meta.url);
143 |
144 | // load it and go!
145 | const data = await d3.json(url);
146 | ```
147 |
148 | ### Changed
149 |
150 | - The Nunjucks environment is now allowed to cache templates in production mode. Probably won't change much speed wise, but ever so slightly more efficient.
151 |
152 | ## [0.30.0] - 2021-01-18
153 |
154 | ### Added
155 |
156 | A new experimental custom Rollup plugin has been added that provides an optimized method for importing data files in JavaScript. If a JSON, CSV, or TSV file is imported using the prefix `dataset:*` it will be added to the bundle either directly as an Object or Array literal (if under 10K in size) or rendered as a string within a `JSON.parse` call.
157 |
158 | It has been documented that [parsing a string within `JSON.parse` is much, much faster](https://v8.dev/blog/cost-of-javascript-2019#json) on average than directly passing in JavaScript, and typically this is the very first step when data is being loaded manually (with `d3-fetch`'s `json` or `csv` functions, etc.). This makes it possible to import (or even better — dynamically import) data without having to deploy it as a file or inject it into HTML to be parsed.
159 |
160 | An example of how to use it:
161 |
162 | ```js
163 | import data from 'dataset:./assets/data.json';
164 | // or dynamically
165 | const data = await import('dataset:./assets/data.json');
166 | ```
167 |
168 | ## [0.29.0] - 2021-01-13
169 |
170 | ### Added
171 |
172 | - CSS within Svelte components is now **supported**. This means any CSS that's written within Svelte components will be included in the `{% script %}` entrypoint bundle that is added to a page.
173 | - Additional variables are now available on the `page` template context object (previously `current_page`) - in addition to `page.absoluteUrl`, `page.url` represents the project-relative URL. `page.inputPath` represents the project-relative path to the original input template, and `page.outputPath` represents the project-relative output path.
174 |
175 | ### Changed
176 |
177 | - The file watcher logic is now a little smarter and keeps track of dependencies directly in the engines (except for Rollup, which manages this itself). This is a small step toward having a much richer dependency graph for builds.
178 | - The `current_page` template context object has been renamed to `page`. `current_page` however will continue to exist until `1.0`.
179 |
180 | ## [0.28.0] - 2020-12-30
181 |
182 | ### Added
183 |
184 | - It's now possible to supply custom tags (`{% custom variable1, variable2 %}`) to Nunjucks via the `baker.config.js` file. It is very similar to how you add custom filters.
185 |
186 | How to add one:
187 |
188 | ```js
189 | // baker.config.js
190 | module.exports = {
191 | // ...
192 | nunjucksTags: {
193 | author(firstName, lastName) {
194 | return `
By ${firstName} ${lastName}
`;
195 | },
196 | },
197 | };
198 | ```
199 |
200 | How to use one:
201 |
202 | ```html
203 | {% author "Arthur", "Barker" %}
204 | ```
205 |
206 | > Heads up! Nunjucks **requires** a comma between arguments.
207 |
208 | And the output:
209 |
210 | ```html
211 |
By Arthur Barker
212 | ```
213 |
214 | ### Changed
215 |
216 | - Async nunjucks tags now _must_ return a Promise. This abstracts away some of Nunjucks' warts and the expectation of a callback to enable async tags.
217 | - Because the built-in `inject` tag was async it now returns a Promise to match the new interface.
218 |
219 | ## [0.27.1] - 2020-12-14
220 |
221 | ### Added
222 |
223 | - Because users of `baker.config.js` no longer have access to the Baker instance, the function that resolves static files is now also available on the Nunjucks instance at `getStaticPath`.
224 |
225 | ## [0.27.0] - 2020-12-14
226 |
227 | ### Changed
228 |
229 | - A behind-the-scenes change, but the custom Rollup plugin for injecting imports into entrypoints has been replaced. This rids Baker of a bug that surfaces when attempting to use dynamic imports.
230 |
231 | ## [0.26.0] - 2020-10-05
232 |
233 | ### Added
234 |
235 | - Added TypeScript support to Svelte files via `svelte-preprocess`.
236 | - Added an exported `svelte.config.js` file so templates and other tools that need to mirror Baker's `svelte-preprocess` options can do so easily.
237 |
238 | ### Changed
239 |
240 | - Moved to `premove` from `rimraf` for directory-emptying tasks.
241 |
242 | ## [0.25.0] - 2020-08-14
243 |
244 | ### Added
245 |
246 | - The `jsonScript` filter is now built-in to Baker's Nunjucks' environment. [Much like the Django version](https://docs.djangoproject.com/en/dev/ref/templates/builtins/#json-script), this filter safely outputs an object as JSON, wrapped in a
260 | ```
261 |
262 | - Attempting to use a JavaScript entrypoint that does not exist because compiling failed or because it was not configured as an entrypoint will now throw a more explicit (and helpful) error.
263 |
264 | - It's now possible to use ESM imports/exports when writing the `baker.config.js` file. Hopefully this will make context switching less annoying - before it was the only user-facing JavaScript file that required CommonJS syntax.
265 |
266 | ### Changed
267 |
268 | - The `static`, `staticabsolute` and `inject` blocks will now always throw an error if a valid file cannot be found. Previously it would silently (and intentionally) fail so a missing file wasn't the end of the world while in development. Maybe this will be too drastic of a change but we'll have to see. Too often folks have a silent failure in development and don't realize it until their build fails in production.
269 |
270 | - Nunjucks blocks and filters have been reorganized within Baker. Nothing user-facing should be altered by this.
271 |
272 | ## [0.24.1] - 2020-08-11
273 |
274 | ### Fixed
275 |
276 | - Bumped `mini-sync` to 0.3.0 to catch a downstream change to do what we already thought was happening - all files served by the dev server should be receiving explicit `no-cache` Cache Control headers.
277 |
278 | ## [0.24.0] - 2020-08-03
279 |
280 | ### Changed
281 |
282 | - Custom Nunjucks filters now have a reference to the current instance of the Nunjucks engine available at `this`. Most filters will never need this, but we have a few cases where filters were hacking access in and we don't wanna break everything.
283 |
284 | ### Fixed
285 |
286 | - The Nunjucks custom `log` filter now returns the input value so Nunjucks will not complain about a null or undefined output.
287 |
288 | ## [0.23.0] - 2020-08-03
289 |
290 | ### Added
291 |
292 | - It's now possible to use a configuration file to pass options to Baker when it is ran using the CLI. This is the **preferred** method for using Baker.
293 |
294 | By default the CLI tool looks for a file called `baker.config.js` in the `input` directory when the `--config` (or `-c`) paramter is passed bare. You can also pass a path to a configuration file if you've given it another name or put it in another directory. If you _do not_ pass `--config` it will use the defaults instead and any other parameters you pass.
295 |
296 | ```sh
297 | # will look for "baker.config.js" in the current directory
298 | baker bake --config
299 |
300 | # will load the config in "my-config.js" in the current directory
301 | baker bake --config my-config.js
302 |
303 | # will not use any config *at all* even if it exists, and use all default options other than "input"
304 | baker bake --input my-project-directory
305 | ```
306 |
307 | The configuration file should export an `object` off of `module.exports`. All options are optional, and Baker will still use the smart defaults the previous iteration of the CLI used. Only set things you want to explicitly change/add!
308 |
309 | ```js
310 | // baker.config.js
311 | module.exports = {
312 | // a custom domain for all resolved URLs
313 | domain: 'our-news-domain',
314 |
315 | // we want to use the static root feature, so we supply the path
316 | staticRoot: '/static/',
317 |
318 | // use createPages to generate pages on the fly
319 | createPages(createPage, data) {
320 | for (const title of data.titles) {
321 | createPage('template.html', `${title}.html`, {
322 | context: { title },
323 | });
324 | }
325 | },
326 |
327 | // pass an object of filters to add to Nunjucks
328 | nunjucksFilters: {
329 | square(n) {
330 | n = +n;
331 |
332 | return n * n;
333 | },
334 | },
335 | };
336 | ```
337 |
338 | - It's now possible to add new Nunjucks filters using the `nunjucksFilters` configuration method. While it was always technically possible to add new filters before by reaching into Baker's instance of Nunjucks, this is a more user-friendly option that is available via the new config file method.
339 |
340 | `nunjucksFilters` should be an object, where each key is the name of the filter, and the key's value is the function to call when the filter is used.
341 |
342 | ```js
343 | // baker.config.js
344 | module.exports = {
345 | nunjucksFilters: {
346 | square(value) {
347 | const n = +value;
348 |
349 | return n * n;
350 | },
351 | },
352 | };
353 | ```
354 |
355 | ```html
356 | {% set value = 5 %}
357 | ```
358 |
359 | ```html
360 | {{ value|square }} // 25
361 | ```
362 |
363 | - New `log` filter in Nunjucks templates that allows you to log any variable or value to the terminal's console.
364 |
365 | ```html
366 | {{ value|log }} // this variable should log in your terminal
367 | ```
368 |
369 | ### Changed
370 |
371 | - Templates are now rendered sequentially instead of in parallel in an attempt to encourage some consistency in the order of errors being thrown. It's not uncommon to have an error present in multiple pages but because each one races each other to render it's not always the same page that throws. It's maddening. This _may_ be slightly slower in bigger projects but we shall see.
372 |
373 | ## [0.22.0] - 2020-07-20
374 |
375 | ### Added
376 |
377 | - It's now possible to dynamically generate HTML outputs by passing an optional `createPages` function when you create a `Baker` instance.
378 |
379 | ```js
380 | /**
381 | * "createPages" is a function to call for each page you want created
382 | * "data" is the quaff generated contents of the "_data" folder
383 | */
384 | function createPages(createPage, data) {
385 | // use whatever parts of the data context (or external sources!) to determine
386 | // what pages should be generated
387 | for (const title of data.titles) {
388 | // call createPage for each one, passing in the template to use within
389 | // _layouts, where to output it in the output (_dist) folder, and optional
390 | // additional context
391 | createPage('template.html', `${title}.html`, {
392 | context: { title },
393 | });
394 | }
395 | }
396 |
397 | const baker = new Baker({
398 | ...,
399 | createPages,
400 | });
401 | ```
402 |
403 | This works whether you're running the development server locally or building for production.
404 |
405 | If an optional additional context is passed, it will be merged with the global context **only** for that render and have precedence, meaning any overlapping keys will contain what was passed locally to `createPage` even if it also exists in the global context. It's recommended to do something similar to above and "namespace" your provided local context to lessen the chance of an unexpected overwrite.
406 |
407 | ### Changed
408 |
409 | - Moved from `rollup-plugin-babel` to the namespaced `@rollup/plugin-babel`.
410 |
411 | ## [0.21.0] - 2020-06-22
412 |
413 | ### Added
414 |
415 | - `.json`, `.geojson` and `.topojson` files in the `assets` directory will now have hashes generated and work like you'd expect with `{% static %}`. In production these files will also be minified.
416 |
417 | ### Changed
418 |
419 | - Baker no longer uses `hasha` to calculate file hashes and instead rolls its own with `crypto`, dropping two dependencies.
420 |
421 | ## [0.20.0] - 2020-06-17
422 |
423 | ### Added
424 |
425 | A new experimental Rollup plugin has been added to `baker` to provide an additional way to pull primitive values from files in the `_data` folder into JavaScript files. By importing a value from a special `data:*` path you can use the value directly.
426 |
427 | So if there was `meta.json` file in your `_data` folder:
428 |
429 | ```json
430 | {
431 | "breed": "corgi",
432 | "names": ["Abe", "Winston", "Willow"]
433 | }
434 | ```
435 |
436 | Then you could tap into it like this:
437 |
438 | ```js
439 | import breed from 'data:meta.breed';
440 |
441 | console.log(breed); // "corgi"
442 | ```
443 |
444 | However - to prevent any excessively large imports this plugin will prevent the import of anything that's not a primitive value (number, boolean, string, etc.). This means _no_ arrays or objects.
445 |
446 | ```js
447 | import names from 'data:meta.names'; // will throw a Rollup error!
448 | ```
449 |
450 | ### Changed
451 |
452 | - `postcss` will now be ran against any CSS in development as well. This prevents the (increasingly) rare case of where a CSS property only has support with a prefix. (`appearance: none` was the driver for this.) This could cryptically break in development and _then_ work in production, which is about as non-ideal as you can get.
453 | - `fs-extra` has been purged from the library in favor of native `fs.promises` and `rimraf`.
454 | - The CLI command now throws proper `process.exit()` calls.
455 | - The dev server (via `mini-sync`) now waits for the initial build to succeed before attempting to serve. This should help prevent partial serves and throw more helpful errors if there is something critically wrong without leaving the dev server in limbo.
456 | - We now use `colorette` for all our terminal coloring needs.
457 |
458 | ### Fixed
459 |
460 | - Failures to process a file in the `_data` directory will now throw legitmate errors via `quaff`. In the case of JSON this means you'll get actually useful line numbers.
461 |
462 | ## [0.20.0-alpha.0] - 2020-02-09
463 |
464 | ### Added
465 |
466 | - It's now possible to pass a `staticRoot` path to Baker, which will make every non-HTML engine output into the `staticRoot` **relative** to `output`. This is intented to make multi-page deploys more viable in certain scenarios.
467 |
468 | ## [0.19.0] - 2020-02-06
469 |
470 | ### Added
471 |
472 | - Each HTML page generated by Nunjucks now has access to the local context variable `current_page`. As of this release the only value in this object is `current_page.absolute_url`, which is intended to replace the global `CURRENT_URL`.
473 |
474 | ### Removed
475 |
476 | - The `CURRENT_URL` Nunjucks global is no longer available, and has been replaced by the local context object `current_page`. Please note this now means any usage of `current_page` **must** be passed into macros, who do not have access to the local context.
477 |
478 | ### Fixed
479 |
480 | - The `CURRENT_URL` Nunjucks global was subject to a race condition when Baker is in multiple-page output mode due to the async render method. This means it was possible for an HTML page to use the wrong `CURRENT_URL`. Now, the current URL of a page will appear on a local context variable called `current_page.absolute_url`, guaranteeing that each page can only ever see it's own `current_page` context.
481 |
482 | ## [0.18.2] - 2020-02-05
483 |
484 | ### Fixed
485 |
486 | - The included `preload` via `{% script %}` now passes `crossorigin`.
487 |
488 | ## [0.18.1] - 2020-02-05
489 |
490 | ### Fixed
491 |
492 | - The preload section of the `{% script %}` block now accounts for the `pathPrefix` and resolves relative to it.
493 |
494 | ## [0.18.0] - 2020-02-05
495 |
496 | ### Added
497 |
498 | - It's now possible to pass a second flag to the `{% script %}` block that instructs it to include any scripts that are candidates for preloading. This is recommended in browsers that support `rel=preload` in order to assist the browser in efficiently loading assets. You should **only** use this if something like [Lighthouse](https://developers.google.com/web/tools/lighthouse/) is suggesting it. To activate it, just pass `true` as the second parameter to `{% script %}` and Baker will do the rest.
499 |
500 | ```html
501 | {% script 'app', true %}
502 | ```
503 |
504 | ## [0.17.0] - 2020-02-04
505 |
506 | ### Added
507 |
508 | - `dotenv-expand` has been added to our `.env` file logic, allowing for tapping into existing environment variables to build values `baker` can see. the `BAKER_` prefix is still enforced, however - but this provides a way to morph existing variables into compatible ones.
509 |
510 | ### Fixed
511 |
512 | - The reworked `inject` function from `0.15.0` did not account for local development when a manifest does not exist for `AssetsEngine` output. This has been fixed. It instead will look for the local version of the file in `development` and continue to error out in `production` if the manifest check fails.
513 |
514 | ## [0.16.1] - 2020-01-19
515 |
516 | ### Fixed
517 |
518 | - `@babel/preset-typescript` also needs to know what the JSX pragma is so it knows to ignore it. This patch ensures both `@babel/preset-typescript` and `@babel/plugin-transform-react-jsx` get passed the same one.
519 |
520 | ## [0.16.0] - 2020-01-19
521 |
522 | ### Added
523 |
524 | - Added support for TypeScript (`.ts`, `.tsx`) files in the `scripts` directory via `@babel/preset-typescript`. They are also allowed as `entrypoints` if passed. Actual type-checking is left up to the user, all this does is remove any TypeScript artifacts from the files - BYO `tsconfig.json` and `tsc` calls.
525 |
526 | ## [0.15.0] - 2020-01-17
527 |
528 | ### Added
529 |
530 | - Added a reworked `inject` block, which allows for inserting the contents of a file **post** processing directly into the HTML. This is useful for potentially "injecting" CSS or JavaScript into the page.
531 |
532 | ## [0.14.0] - 2020-01-16
533 |
534 | ### Added
535 |
536 | - Video files (`.mp4`, `.webm`) are now recognized by `AssetsEngine` and will be included in any hashing.
537 |
538 | ## [0.13.2] - 2020-01-10
539 |
540 | ### Fixed
541 |
542 | - Some `dependencies` got moved to `devDependencies`, meaning you wouldn't have got them on install. Oops.
543 |
544 | ## [0.13.1] - 2020-01-10
545 |
546 | ### Fixed
547 |
548 | - `Baker.pathPrefix` is now set to `/` in `development` mode so a passed `pathPrefix` does not break anything in serve mode.
549 |
550 | ## [0.13.0] - 2020-01-10
551 |
552 | ### Added
553 |
554 | - The Nunjucks environment now includes a new global named `CURRENT_URL`. This represents the final URL of each generated page that can be used in its template. It's based on a combination of the provided `domain`, `pathPrefix` and clean (without `index.html` appended) path of the output HTML itself.
555 |
556 | ## [0.12.0] - 2020-01-09
557 |
558 | ### Added
559 |
560 | - Added new built-in `date` filter to Nunjucks, which allows for formatting of an ISO date string or Date object with `date-fns` [formatting function](https://date-fns.org/v2.8.1/docs/format).
561 | - Added a new parameter that must be passed to `new Baker()` — `domain`. This is used by `staticabsolute` to prepare absolute project URLs. (May become optional later for scenarios where this doesn't matter.)
562 | - Added new `staticabsolute` block, which makes it possible to build absolute URLs to project files.
563 |
564 | ## [0.11.0] - 2019-12-06
565 |
566 | ### Added
567 |
568 | - Font files (`.woff2`, `.woff`, `.ttf`, `.otf`) are now recognized by `AssetsEngine` and will be included in any hashing.
569 |
570 | ### Fixed
571 |
572 | - Baker now picks up images with without all lowercase extensions and includes them the compression and hashing process.
573 |
574 | ## [0.10.0] - 2019-12-03
575 |
576 | ### Added
577 |
578 | - The function that resolves static files is now available on a Baker instance as `getStaticPath`. This enables users of Baker to tap into the file resolution logic however they see fit.
579 |
580 | ## [0.9.0] - 2019-11-18
581 |
582 | ### Added
583 |
584 | - Modern JavaScript builds now use [`@babel/preset-modules`](https://github.com/babel/preset-modules). This should result in even smaller modern bundles that natively support features that already exist in ~85% of browsers.
585 |
586 | ### Removed
587 |
588 | - Automatic web polyfill injection has been removed. It's just too much magic going on, and we shouldn't assume that every single thing will need `fetch` + `intersection-observer` + `classlist` injected into it. (JavaScript features are still polyfilled via `core-js`. In other words if it's something you'd be able to do in Node.js it's handled.) The gains of keeping a few polyfills out of the modern build aren't worth the confusion. However this does mean users are now responsible for importing their own polyfills.
589 |
590 | ## [0.8.0] - 2019-11-03
591 |
592 | ### Added
593 |
594 | - The Rollup engine now supports both Svelte (`.svelte` files) and Preact (the usage of JSX) as options for JavaScript-based HTML templating.
595 |
596 | ### Changed
597 |
598 | - `browser-sync` has been replaced with [`mini-sync`](https://github.com/rdmurphy/mini-sync). `browser-sync` was one of the largest packages installed in `baker`, and this should lead to quicker install times.
599 |
600 | ### Removed
601 |
602 | - The old legacy Rollup engine has been deleted and the one previously called `rollup2.js` has taken its place.
603 |
604 | ## [0.7.0] - 2019-10-18
605 |
606 | ### Added
607 |
608 | - Support for correctly formatted environment variables that are passed to `rollup-plugin-replace` has been added. Any environment variable that begins with `BAKER_` will be read and converted to the `process.env.BAKER_*` format that can be used in JavaScript files. Any environmental variables that do not have a match are ignored.
609 |
610 | It's also possible to manage these with a `.env` in the root of your project. The same rule regarding the `BAKER_` prefix applies.
611 |
612 | ## [0.6.0] - 2019-09-17
613 |
614 | ### Added
615 |
616 | - Two custom functions have been added to the `sass` renderer — `static-url` and `static-path`. These are implemented against the Node.js API (and not within a Sass file) because they need to reference the static asset manifests. They are used in the same scenarios as the `{% static %}` block in Nunjucks templates — you need to reference the path to a static asset in your project, but need it to be given the correct hash prefix on production builds.
617 |
618 | `static-url` is meant to be a shortcut for anything you'd normally put inside of `url()`, which it will include for you.
619 |
620 | _SCSS_
621 |
622 | ```scss
623 | body {
624 | background-image: static-url('assets/background.png');
625 | }
626 | ```
627 |
628 | _CSS_
629 |
630 | ```css
631 | body {
632 | background-image: url(/assets/background.123abc.png);
633 | }
634 | ```
635 |
636 | `static-path` only adjusts the path and returns it as a string. This will probably be less used, but it's there as an escape hatch if you need it.
637 |
638 | ```scss
639 | body {
640 | background-image: url(static-path('assets/background.png'));
641 | }
642 | ```
643 |
644 | _CSS_
645 |
646 | ```css
647 | body {
648 | background-image: url(/assets/background.123abc.png);
649 | }
650 | ```
651 |
652 | ### Changed
653 |
654 | - Now only valid images will receive the file hash in production mode. This is imperfect, but better than every random asset getting a hash unnecessarily and causing issues when they're used. (Looking at you, `.gltf` files.) Ideally this would be smarter, but not quite sure how to go about that yet.
655 |
656 | ## [0.5.0] - 2019-09-04
657 |
658 | ### Added
659 |
660 | - Nunjucks templates now have a better error logger. It's not perfect, but should help find specific lines causing issues.
661 | - Template files in the layout directory are now watched during a serve - if any changes are made templates are regenerated.
662 | - Files in the `data` directory are now watched during a serve and will trigger a template build.
663 |
664 | ### Changed
665 |
666 | - This package is now deployed on `npm` at `@datagraphics/baker` instead of `@datadesk/baker`, which has been deprecated.
667 |
668 | ## [0.4.0] - 2019-09-03
669 |
670 | ### Added
671 |
672 | - Legacy script builds now use `core-js` to polyfill and add features that may be missing in those browsers. This will likely cause the `iife` build to be bigger than it should be, but this prevents users from having to whack-a-mole issues with IE 11. It should just work.
673 | - Polyfills for both the modern and legacy are automatically inserted into every entrypoint, with the assumption there's a base set of features we should expect to be there. For modern builds, it's support for dynamic imports and IntersectionObserver. For legacy builds, it's fetch, Element.classList and IntersectionObserver.
674 |
675 | ### Changed
676 |
677 | - The engine for Rollup has been rewritten to be much smarter about how it navigates modern and legacy builds. This also does away with SystemJS in favor of native modules for browsers that support it, and an `iife` build for browsers that do not.
678 |
679 | ## [0.3.0] - 2019-08-16
680 |
681 | ### Added
682 |
683 | - Added `AssetsEngine` for management of generic assets files in a build. By default it looks for an `assets` directory in the input directory.
684 |
685 | ### Changed
686 |
687 | - The `ImagesEngine` is no more and has been merged into `AssetsEngine`. This means that images _must_ be in the `assets` directory to be found and handled.
688 |
689 | ## [0.2.1] - 2019-08-16
690 |
691 | ### Fixed
692 |
693 | - A `pathPrefix` should always have a leading slash to ensure pathing resolution works.
694 |
695 | ## [0.2.0] - 2019-08-08
696 |
697 | ### Changed
698 |
699 | - The serve task now runs all the engines in an initial pass before activating the server. This ensures that the local development URL is not presented as available before it truly is.
700 |
701 | ## [0.1.0] - 2019-08-07
702 |
703 | ### Added
704 |
705 | - Initial release.
706 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2019 Los Angeles Times
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 |
3 | `@datagraphics/baker` is a build tool by and for the Los Angeles Times. The Times uses it to build the static pages published at latimes.com/projects. You can use it however you'd like.
4 |
5 | An example of how The Times puts the package to use is available at [datadesk/baker-example-page-template](https://github.com/datadesk/baker-example-page-template).
6 |
7 | [](https://www.npmjs.org/package/@datagraphics/baker)
8 |
9 | ## Requirements
10 |
11 | * [Node.js](https://nodejs.org/en/) version 14 and higher
12 | * [Node Package Manager](https://www.w3schools.com/whatis/whatis_npm.asp)
13 |
14 | ## Installation
15 |
16 | ```sh
17 | npm install -D @datagraphics/baker
18 | ```
19 |
20 | ## What is Baker and why do you use it?
21 |
22 | Baker is a development environment that can be converted into a static website that’s ready for the web. With a minimal amount of HTML, CSS and JavaScript, you can publish a project. The Los Angeles Times uses Baker to write custom code for projects that aren’t possible within the rigid templates of our content management system.
23 |
24 | ## Does anyone else use Baker?
25 |
26 | Yes. Here are some examples of Baker is use outside of the Los Angeles Times.
27 |
28 | * [AMSAT’s amateur satellite index](https://amsat.org/amateur-satellite-index)
29 | * The ["First Visual Story"](https://palewi.re/docs/first-visual-story/) training tutorial by [Ben Welsh](https://palewi.re/who-is-ben-welsh/), [Armand Emamdjomeh](http://emamd.net/) and [Vanessa Martinez](https://www.vanessa-martinez.com/)
30 | * [e.e. cummings free poetry archive](https://cummings.ee/) by [Ben Welsh](https://palewi.re/who-is-ben-welsh/)
31 | * [Noodle Tracker](https://noodletracker.com/) by [Matt Stiles](https://mattstiles.me/)
32 | * [hotsauce.gay](https://hotsauce.gay/) and [men who don't move](https://caseymm.github.io/men-who-dont-move/) by [Casey Miller](https://caseymmiller.com/)
33 | * A variety of news applications by [ProPublica](https://propublica.org), including ["Does Your Local Museum or University Still Have Native American Remains?"](https://projects.propublica.org/repatriation-nagpra-database/) and ["Look Up Which Fortune 500 Companies Fund Election Deniers"](https://projects.propublica.org/fortune-500-company-election-deniers-jan-6/).
34 | * ["Did your neighborhood turn out to vote?"](https://projects.thecity.nyc/zeldin-hochul-election-voter-turnout-nyc/) and other features by [THE CITY](https://www.thecity.nyc/)
35 | * [Maryland precinct-level election results](https://www.thebaltimorebanner.com/politics-power/state-government/precinct-level-governor-election-vote-data-O25RWFHG35DEFCYOZNZDVRS374/) by [The Baltimore Banner](https://www.thebaltimorebanner.com/)
36 | * [moneyinpolitics.wtf](https://moneyinpolitics.wtf/) by [Ben Welsh](https://palewi.re/who-is-ben-welsh/), Derek Willis, Anu Narayanswamy and Agustin Armendariz
37 |
38 | If you know of other examples, please add them to the list.
39 |
40 | ## How does Baker work?
41 |
42 | Baker brings together a bunch of different technologies.
43 |
44 | The HTML templating is powered by [Nunjucks](https://mozilla.github.io/nunjucks/), giving us a Jinja2-like experience for organizing and creating our HTML pages. This is also very similar to the templating language used in Django.
45 |
46 | CSS styles are written using the preprocessor [Sass](https://sass-lang.com/). Sass enhances CSS by adding features that don't exist in CSS yet like nesting, mixins, inheritance and other tricks. Baker also uses the postprocessor called Autoprefixer, which automatically adds special prefixes to our CSS for browser support. (`--webkit`, `--moz`, etc.)
47 |
48 | JavaScript is bundled using [Rollup](https://www.rollupjs.org/guide/en/), which makes it possible for us to write modern JavaScript that gets optimized and prepared in a way that makes it load as fast as possible for our users. Code we write is passed through a JavaScript compiler called [Babel](https://babeljs.io/), which rewrites our code to make sure it works in all the browsers we support.
49 |
50 | Data imports, powered by [quaff](https://www.npmjs.com/package/quaff), allow for easily imported structured data files into templates, which is useful for making data visualizations.
51 |
52 | ## How do I get started using it?
53 |
54 | The repository at [github.com/datadesk/baker-example-page-template](https://github.com/datadesk/baker-example-page-template) is our premade starter that comes with HTML, styles and scripts ready for experimentation. It also includes GitHub Actions that can deploy staging and production version of your page. It works after only minimal configuration. You could customize it to match the look and feel of your site.
55 |
56 | ## Contributing
57 |
58 | [Fork](https://docs.github.com/en/get-started/quickstart/fork-a-repo) the repository and [clone](https://docs.github.com/en/repositories/creating-and-managing-repositories/cloning-a-repository) it locally. The enter the code directory and install the package's dependencies.
59 |
60 | ```sh
61 | npm install
62 | ```
63 |
64 | [Branch](https://git-scm.com/book/en/v2/Git-Branching-Basic-Branching-and-Merging) off. Make any changes. Preview them with the test server.
65 |
66 | ```sh
67 | npm start
68 | ```
69 |
70 | Run our tests.
71 |
72 | ```sh
73 | npm run build
74 | ```
75 |
76 | Once they pass, your changes should be briefly documented in the `CHANGELOG.md` file under the `[Unreleased]` header. Depending on the type of change you are making, you may need to add a new subheader as defined by [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). For example, if you are changing how a feature works, you may need to add a `### [Changed]` subhead.
77 |
78 | [Commit](https://git-scm.com/docs/git-commit). Submit a [pull request](https://docs.github.com/en/github/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/creating-a-pull-request).
79 |
80 | ## Releasing
81 |
82 | This package is distributed using npm. To publish a new release, you will need to have an [npmjs](https://www.npmjs.com/) account with ownership of the [@datagraphics/baker](https://www.npmjs.com/package/@datagraphics/baker) namespace.
83 |
84 | Next you should use npm's version command to up the version number. You have to decide if you're a major, minor or patch release. If you're unsure, review the standards defined at [semver.org](https://semver.org/). Then run one of the commands below. The code will be updated appropriately.
85 |
86 | ```sh
87 | # Pick one and only one!
88 | npm version major
89 | npm version minor
90 | npm version patch
91 | ```
92 |
93 | Rename the `[Unreleased]` section of the `CHANGELOG.md` with the same version number. Commit.
94 |
95 | ```sh
96 | git add CHANGELOG.md
97 | git commit -m "Updated CHANGELOG"
98 | ```
99 |
100 | Release the new version of the package.
101 |
102 | ```sh
103 | npm publish
104 | ```
105 |
106 | Push your work to GitHub, including tag created by the `npm version` command.
107 |
108 | ```sh
109 | git push origin main --tags
110 | ```
111 |
112 | Create a new release on GitHub at [github.com/datadesk/baker/releases](https://github.com/datadesk/baker/releases) with the same version number. Paste the changelog entry into the post as a bullet list.
113 |
--------------------------------------------------------------------------------
/bin/bake.js:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env node
2 |
3 | // native
4 | import { bold, green, red } from 'colorette';
5 | import { resolve } from 'path';
6 |
7 | // packages
8 | import debug from 'debug';
9 | import mri from 'mri';
10 | import { rollup } from 'rollup';
11 | import requireFromString from 'require-from-string';
12 |
13 | // local
14 | import { Baker } from '../lib/index.js';
15 | import { logErrorMessage } from '../lib/utils.js';
16 |
17 | const logger = debug('baker:cli');
18 |
19 | const OUTPUT_DIR = '_dist';
20 | const SCREENSHOT_DIR = '_screenshot';
21 |
22 | const defaultConfigFile = 'baker.config.js';
23 |
24 | const defaultConfig = {
25 | assets: 'assets',
26 | createPages: undefined,
27 | data: '_data',
28 | domain: undefined,
29 | embeds: 'embeds',
30 | entrypoints: 'scripts/app.js',
31 | input: process.cwd(),
32 | layouts: '_layouts',
33 | nunjucksVariables: undefined,
34 | nunjucksFilters: undefined,
35 | nunjucksTags: undefined,
36 | minifyOptions: undefined,
37 | svelteCompilerOptions: undefined,
38 | output: OUTPUT_DIR,
39 | pathPrefix: '/',
40 | port: 3000,
41 | staticRoot: '',
42 | crosswalkPath: undefined,
43 | };
44 |
45 | function getDefaultFromConfig(module) {
46 | return module.__esModule ? module.default : module;
47 | }
48 |
49 | async function compileAndLoadConfig(pathToConfig) {
50 | const bundle = await rollup({
51 | external: () => true,
52 | input: pathToConfig,
53 | treeshake: false,
54 | });
55 |
56 | const {
57 | output: [{ code }],
58 | } = await bundle.generate({
59 | exports: 'named',
60 | format: 'cjs',
61 | interop: 'auto',
62 | });
63 | const loadedConfig = requireFromString(code, pathToConfig);
64 |
65 | return getDefaultFromConfig(loadedConfig);
66 | }
67 |
68 | async function prepareConfig(inputOptions) {
69 | // the input directory everything is relative to
70 | const input = inputOptions.input;
71 |
72 | // a config parameter was passed
73 | if (inputOptions.config) {
74 | // we check to see if it was passed as a boolean and use our default path to the config, otherwise we use what was given
75 | const pathToConfig = resolve(
76 | input,
77 | inputOptions.config === true ? defaultConfigFile : inputOptions.config
78 | );
79 |
80 | inputOptions = await compileAndLoadConfig(pathToConfig);
81 | }
82 |
83 | // prep a helper function to resolve paths against input
84 | const resolver = (key) => inputOptions[key] || defaultConfig[key];
85 |
86 | const options = {};
87 |
88 | options.assets = resolver('assets');
89 | options.createPages = resolver('createPages');
90 | options.data = resolver('data');
91 | options.domain = resolver('domain');
92 | options.embeds = resolver('embeds');
93 | options.entrypoints = resolver('entrypoints');
94 | options.input = resolver('input');
95 | options.layouts = resolver('layouts');
96 | options.nunjucksVariables = resolver('nunjucksVariables');
97 | options.nunjucksFilters = resolver('nunjucksFilters');
98 | options.nunjucksTags = resolver('nunjucksTags');
99 | options.minifyOptions = resolver('minifyOptions');
100 | options.output = resolver('output');
101 | options.pathPrefix = resolver('pathPrefix');
102 | options.port = resolver('port');
103 | options.staticRoot = resolver('staticRoot');
104 | options.svelteCompilerOptions = resolver('svelteCompilerOptions');
105 | options.crosswalkPath = resolver('crosswalkPath');
106 |
107 | return options;
108 | }
109 |
110 | const mriConfig = {
111 | alias: {
112 | a: 'assets',
113 | c: 'config',
114 | d: 'data',
115 | e: 'entrypoints',
116 | i: 'input',
117 | l: 'layouts',
118 | o: 'output',
119 | p: 'pathPrefix',
120 | s: 'staticRoot',
121 | },
122 | default: {
123 | input: process.cwd(),
124 | },
125 | };
126 |
127 | /**
128 | * The function that runs when the CLI is ran.
129 | *
130 | * @param {string[]} args The provided args
131 | */
132 | async function run(args) {
133 | const { _, ...flags } = mri(args, mriConfig);
134 |
135 | const command = _[0];
136 | const config = await prepareConfig(flags);
137 |
138 | logger('command:', command);
139 | logger('resolved input flags:', config);
140 |
141 | const baker = new Baker(config);
142 |
143 | switch (command) {
144 | case 'bake':
145 | case 'build':
146 | try {
147 | await baker.bake();
148 |
149 | console.log(green(bold('The build was a success!')));
150 | } catch (err) {
151 | console.log(
152 | red(bold("Build failed. Here's what possibly went wrong:\n"))
153 | );
154 | logErrorMessage(err);
155 | process.exit(1);
156 | }
157 | break;
158 | case 'screenshot':
159 | // Change a few config options for taking screenshots
160 | const screenshotConfig = { ...config, output: SCREENSHOT_DIR };
161 | const screenshotBaker = new Baker(screenshotConfig);
162 |
163 | try {
164 | await screenshotBaker.screenshot();
165 |
166 | console.log(green(bold('The screenshot was a success!')));
167 | } catch (err) {
168 | console.log(
169 | red(bold("Screenshot failed. Here's what possibly went wrong:\n"))
170 | );
171 | logErrorMessage(err);
172 | process.exit(1);
173 | }
174 | break;
175 | case 'serve':
176 | await baker.serve();
177 | }
178 | }
179 |
180 | run(process.argv.slice(2)).catch((err) => {
181 | console.error(err);
182 | // we want to throw a real exit value on crash and burn
183 | process.exit(1);
184 | });
185 |
--------------------------------------------------------------------------------
/example-simple/_data/titles.json:
--------------------------------------------------------------------------------
1 | ["title1", "title2", "title3", "title4"]
2 |
--------------------------------------------------------------------------------
/example-simple/_layouts/template.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | A templated page
7 | {% block styles %}{% endblock styles %}
8 | {% script 'app' %}
9 |
10 |
11 | {% block content %}{% endblock content %}
12 |
13 |
14 |
--------------------------------------------------------------------------------
/example-simple/baker.config.js:
--------------------------------------------------------------------------------
1 | import { intcomma } from 'journalize';
2 |
3 | export default {
4 | // special case because it is in a directory
5 | input: './example-simple',
6 |
7 | // we want to use the static root feature, so we supply the path
8 | staticRoot: '/static/',
9 |
10 | // pathPrefix and domain are required
11 | pathPrefix: '/',
12 | domain: 'https://www.latimes.com',
13 |
14 | // use createPages to generate pages on the fly
15 | createPages(createPage, data) {
16 | for (const title of data.titles) {
17 | createPage('template.html', `${title}.html`, {
18 | context: { title },
19 | });
20 | }
21 | },
22 |
23 | // pass an object of filters to add to Nunjucks
24 | nunjucksFilters: {
25 | otherintcomma: intcomma,
26 | square(n) {
27 | n = +n;
28 |
29 | return n * n;
30 | },
31 | logContext() {
32 | console.log(this.context);
33 |
34 | return 'check console';
35 | },
36 | },
37 |
38 | nunjucksTags: {
39 | doubler(n) {
40 | return `